*.iws
.idea
xtend-gen
+yang-gen-config
+yang-gen-sal
classes
out/
.externalToolBuilders
</scm>
<artifactId>clustering.services-implementation</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>0.4.3-SNAPSHOT</version>
<packaging>bundle</packaging>
<properties>
<!-- Sonar properties using jacoco to retrieve integration test results -->
*
</DynamicImport-Package>
<Embed-Dependency>
- infinispan-core,jgroups,jboss-marshalling-river,jboss-marshalling,jboss-logging,staxmapper,narayana-jta;type=!pom;inline=false
+ infinispan-core,infinispan-commons,jgroups,jboss-marshalling-river,jboss-marshalling,jboss-logging,staxmapper,narayana-jta;type=!pom;inline=false
</Embed-Dependency>
<Embed-Transitive>
true
<exclude>org.infinispan:infinispan-core:*</exclude>
</excludes>
<includes>
- <include>org.infinispan:infinispan-core:[5.3.0.Final]</include>
+ <include>org.infinispan:infinispan-core:[6.0.2.Final]</include>
</includes>
</bannedDependencies>
</rules>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-core</artifactId>
- <version>5.3.0.Final</version>
+ <version>6.0.2.Final</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
+++ /dev/null
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2009 Red Hat Inc. and/or its affiliates and other
- * contributors as indicated by the @author tags. All rights reserved.
- * See the copyright.txt in the distribution for a full listing of
- * individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.infinispan.interceptors.distribution;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.infinispan.CacheException;
-import org.infinispan.commands.FlagAffectedCommand;
-import org.infinispan.commands.remote.ClusteredGetCommand;
-import org.infinispan.commands.write.DataWriteCommand;
-import org.infinispan.commands.write.WriteCommand;
-import org.infinispan.container.entries.InternalCacheEntry;
-import org.infinispan.container.entries.InternalCacheValue;
-import org.infinispan.context.InvocationContext;
-import org.infinispan.context.impl.TxInvocationContext;
-import org.infinispan.distribution.DistributionManager;
-import org.infinispan.factories.annotations.Inject;
-import org.infinispan.interceptors.ClusteringInterceptor;
-import org.infinispan.interceptors.locking.ClusteringDependentLogic;
-import org.infinispan.remoting.responses.ClusteredGetResponseValidityFilter;
-import org.infinispan.remoting.responses.ExceptionResponse;
-import org.infinispan.remoting.responses.Response;
-import org.infinispan.remoting.responses.SuccessfulResponse;
-import org.infinispan.remoting.rpc.ResponseFilter;
-import org.infinispan.remoting.rpc.ResponseMode;
-import org.infinispan.remoting.rpc.RpcOptions;
-import org.infinispan.remoting.transport.Address;
-import org.infinispan.transaction.xa.GlobalTransaction;
-import org.infinispan.util.logging.Log;
-import org.infinispan.util.logging.LogFactory;
-
-
-/**
- * Base class for distribution of entries across a cluster.
- *
- * @author Manik Surtani
- * @author Mircea.Markus@jboss.com
- * @author Pete Muir
- * @author Dan Berindei <dan@infinispan.org>
- * @since 4.0
- */
-public abstract class BaseDistributionInterceptor extends ClusteringInterceptor {
-
- protected DistributionManager dm;
-
- protected ClusteringDependentLogic cdl;
-
- private static final Log log = LogFactory.getLog(BaseDistributionInterceptor.class);
-
- @Override
- protected Log getLog() {
- return log;
- }
-
- @Inject
- public void injectDependencies(DistributionManager distributionManager, ClusteringDependentLogic cdl) {
- this.dm = distributionManager;
- this.cdl = cdl;
- }
-
- @Override
- protected final InternalCacheEntry retrieveFromRemoteSource(Object key, InvocationContext ctx, boolean acquireRemoteLock, FlagAffectedCommand command) throws Exception {
- GlobalTransaction gtx = acquireRemoteLock ? ((TxInvocationContext)ctx).getGlobalTransaction() : null;
- ClusteredGetCommand get = cf.buildClusteredGetCommand(key, command.getFlags(), acquireRemoteLock, gtx);
-
- List<Address> targets = new ArrayList<Address>(stateTransferManager.getCacheTopology().getReadConsistentHash().locateOwners(key));
- // if any of the recipients has left the cluster since the command was issued, just don't wait for its response
- targets.retainAll(rpcManager.getTransport().getMembers());
- ResponseFilter filter = new ClusteredGetResponseValidityFilter(targets, rpcManager.getAddress());
- RpcOptions options = rpcManager.getRpcOptionsBuilder(ResponseMode.WAIT_FOR_VALID_RESPONSE, false)
- .responseFilter(filter).build();
- Map<Address, Response> responses = rpcManager.invokeRemotely(targets, get, options);
-
- if (!responses.isEmpty()) {
- for (Response r : responses.values()) {
- if (r instanceof SuccessfulResponse) {
- InternalCacheValue cacheValue = (InternalCacheValue) ((SuccessfulResponse) r).getResponseValue();
- return cacheValue.toInternalCacheEntry(key);
- }
- }
- }
-
- // TODO If everyone returned null, and the read CH has changed, retry the remote get.
- // Otherwise our get command might be processed by the old owners after they have invalidated their data
- // and we'd return a null even though the key exists on
- return null;
- }
-
- protected final Object handleNonTxWriteCommand(InvocationContext ctx, DataWriteCommand command) throws Throwable {
- if (ctx.isInTxScope()) {
- throw new CacheException("Attempted execution of non-transactional write command in a transactional invocation context");
- }
-
- RecipientGenerator recipientGenerator = new SingleKeyRecipientGenerator(command.getKey());
-
- // see if we need to load values from remote sources first
- remoteGetBeforeWrite(ctx, command, recipientGenerator);
-
- // if this is local mode then skip distributing
- if (isLocalModeForced(command)) {
- return invokeNextInterceptor(ctx, command);
- }
-
- boolean isSync = isSynchronous(command);
- if (!ctx.isOriginLocal()) {
- Object returnValue = invokeNextInterceptor(ctx, command);
- Address primaryOwner = cdl.getPrimaryOwner(command.getKey());
- if (primaryOwner.equals(rpcManager.getAddress())) {
- if (command.isConditional() && !command.isSuccessful()) {
- log.tracef(
- "Skipping the replication of the conditional command as it did not succeed on primary owner (%s).",
- command);
- return returnValue;
- }
- rpcManager.invokeRemotely(recipientGenerator.generateRecipients(), command,
- rpcManager.getDefaultRpcOptions(isSync));
- } else {
- log.tracef("Didn't invoke RPC because primaryOwner (%s) didn't match this node (%s)", primaryOwner,
- rpcManager.getAddress());
- log.tracef("Hashcode is (%s) for Key (%s)",
- command.getKey().hashCode(), command.getKey());
- }
- return returnValue;
- } else {
- Address primaryOwner = cdl.getPrimaryOwner(command.getKey());
- if (primaryOwner.equals(rpcManager.getAddress())) {
- Object result = invokeNextInterceptor(ctx, command);
- if (command.isConditional() && !command.isSuccessful()) {
- log.tracef("Skipping the replication of the conditional command as it did not succeed on primary owner (%s).", command);
- return result;
- }
- List<Address> recipients = recipientGenerator.generateRecipients();
- log.tracef("I'm the primary owner, sending the command to all (%s) the recipients in order to be applied.", recipients);
- // check if a single owner has been configured and the target for the key is the local address
- boolean isSingleOwnerAndLocal = cacheConfiguration.clustering().hash().numOwners() == 1
- && recipients != null
- && recipients.size() == 1
- && recipients.get(0).equals(rpcManager.getTransport().getAddress());
- if (!isSingleOwnerAndLocal) {
- rpcManager.invokeRemotely(recipients, command, rpcManager.getDefaultRpcOptions(isSync));
- }
- return result;
- } else {
- log.tracef("I'm not the primary owner, so sending the command to the primary owner(%s) in order to be forwarded", primaryOwner);
- log.tracef("Hashcode is (%s) for Key (%s)", command.getKey().hashCode(), command.getKey());
-
- Object localResult = invokeNextInterceptor(ctx, command);
- boolean isSyncForwarding = isSync || isNeedReliableReturnValues(command);
- Map<Address, Response> addressResponseMap = rpcManager.invokeRemotely(Collections.singletonList(primaryOwner), command,
- rpcManager.getDefaultRpcOptions(isSyncForwarding));
- if (!isSyncForwarding) return localResult;
-
- return getResponseFromPrimaryOwner(primaryOwner, addressResponseMap);
- }
- }
- }
-
- private Object getResponseFromPrimaryOwner(Address primaryOwner, Map<Address, Response> addressResponseMap) {
- Response fromPrimaryOwner = addressResponseMap.get(primaryOwner);
- if (fromPrimaryOwner == null) {
- log.tracef("Primary owner %s returned null", primaryOwner);
- return null;
- }
- if (!fromPrimaryOwner.isSuccessful()) {
- Throwable cause = fromPrimaryOwner instanceof ExceptionResponse ? ((ExceptionResponse)fromPrimaryOwner).getException() : null;
- throw new CacheException("Got unsuccessful response from primary owner: " + fromPrimaryOwner, cause);
- } else {
- return ((SuccessfulResponse) fromPrimaryOwner).getResponseValue();
- }
- }
-
- protected abstract void remoteGetBeforeWrite(InvocationContext ctx, WriteCommand command, RecipientGenerator keygen) throws Throwable;
-
- interface RecipientGenerator {
-
- Collection<Object> getKeys();
-
- List<Address> generateRecipients();
- }
-
- class SingleKeyRecipientGenerator implements RecipientGenerator {
- private final Object key;
- private final Set<Object> keys;
- private List<Address> recipients = null;
-
- SingleKeyRecipientGenerator(Object key) {
- this.key = key;
- keys = Collections.singleton(key);
- }
-
- @Override
- public List<Address> generateRecipients() {
- if (recipients == null) {
- recipients = cdl.getOwners(key);
- }
- return recipients;
- }
-
- @Override
- public Collection<Object> getKeys() {
- return keys;
- }
- }
-
- class MultipleKeysRecipientGenerator implements RecipientGenerator {
-
- private final Collection<Object> keys;
- private List<Address> recipients = null;
-
- MultipleKeysRecipientGenerator(Collection<Object> keys) {
- this.keys = keys;
- }
-
- @Override
- public List<Address> generateRecipients() {
- if (recipients == null) {
- recipients = cdl.getOwners(keys);
- }
- return recipients;
- }
-
- @Override
- public Collection<Object> getKeys() {
- return keys;
- }
- }
-}
-<infinispan xsi:schemaLocation="urn:infinispan:config:5.3 http://www.infinispan.org/schemas/infinispan-config-5.3.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:infinispan:config:5.3">
+<infinispan>
<global>
<transport>
<properties>
jmxDomain="org.infinispan"
cacheManagerName="SampleCacheManager"/>
</global>
- <default>
- <!-- Configure a synchronous replication cache -->
- <clustering mode="replication">
- <sync/>
- </clustering>
- <!--
- Used to register JMX statistics in any available MBean server
- -->
+
+ <default>
<jmxStatistics enabled="true"/>
- </default>
- <!-- transactionManagerLookupClass="org.infinispan.transaction.lookup.JBossStandaloneJTAManagerLookup" -->
- <namedCache name="transactional-type">
+ <clustering mode="replication">
+ <sync/>
+ </clustering>
+ </default>
+ <namedCache name="transactional-type">
<transaction
transactionManagerLookupClass="org.infinispan.transaction.lookup.JBossStandaloneJTAManagerLookup"
syncRollbackPhase="true"
use1PcForAutoCommitTransactions="true"
autoCommit="true"
lockingMode="OPTIMISTIC"
+ useEagerLocking="true"
useSynchronization="true"
transactionMode="TRANSACTIONAL"
/>
+ <clustering mode="replication">
+ <sync/>
+ </clustering>
</namedCache>
+
</infinispan>
<commons.io.version>2.4</commons.io.version>
<bundlescanner.version>0.4.2-SNAPSHOT</bundlescanner.version>
<usermanager.version>0.4.2-SNAPSHOT</usermanager.version>
- <forwardingrulesmanager.version>0.5.1-SNAPSHOT</forwardingrulesmanager.version>
+ <forwardingrulesmanager.version>0.6.0-SNAPSHOT</forwardingrulesmanager.version>
<statisticsmanager.version>0.5.1-SNAPSHOT</statisticsmanager.version>
<clustering.services.version>0.5.1-SNAPSHOT</clustering.services.version>
<configuration.version>0.4.3-SNAPSHOT</configuration.version>
<topologymanager.version>0.4.2-SNAPSHOT</topologymanager.version>
<protocol_plugin.stub.version>0.4.2-SNAPSHOT</protocol_plugin.stub.version>
<clustering.stub.version>0.4.2-SNAPSHOT</clustering.stub.version>
+ <clustering.services_implementation.version>0.4.3-SNAPSHOT</clustering.services_implementation.version>
<!-- Third party version -->
<jersey-servlet.version>1.17</jersey-servlet.version>
<corsfilter.version>7.0.42</corsfilter.version>
<!-- enforcer version -->
<enforcer.version>1.3.1</enforcer.version>
<xtend.version>2.4.3</xtend.version>
- <xtend.dstdir>${project.build.directory}/generated-sources/xtend-gen</xtend.dstdir>
+ <xtend.dstdir>src/main/xtend-gen</xtend.dstdir>
+ <jmxGeneratorPath>src/main/yang-gen-config</jmxGeneratorPath>
+ <salGeneratorPath>src/main/yang-gen-sal</salGeneratorPath>
</properties>
<dependencyManagement>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services-implementation</artifactId>
- <version>${controller.version}</version>
+ <version>${clustering.services_implementation.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<includeTestSourceDirectory>true</includeTestSourceDirectory>
<sourceDirectory>${project.basedir}</sourceDirectory>
<includes>**\/*.java,**\/*.xml,**\/*.ini,**\/*.sh,**\/*.bat</includes>
- <excludes>**\/target\/,**\/bin\/,**\/target-ide\/</excludes>
+ <excludes>**\/target\/,**\/bin\/,**\/target-ide\/,**\/${jmxGeneratorPath}\/,**\/${salGeneratorPath}\/</excludes>
</configuration>
</plugin>
<plugin>
</execution>
</executions>
</plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ </plugin>
</plugins>
<pluginManagement>
<plugins>
</execution>
</executions>
</plugin>
+ <plugin>
+ <artifactId>maven-clean-plugin</artifactId>
+ <configuration>
+ <filesets>
+ <fileset>
+ <directory>${xtend.dstdir}</directory>
+ <includes>
+ <include>**</include>
+ </includes>
+ </fileset>
+ <fileset>
+ <directory>${jmxGeneratorPath}</directory>
+ <includes>
+ <include>**</include>
+ </includes>
+ </fileset>
+ <fileset>
+ <directory>${salGeneratorPath}</directory>
+ <includes>
+ <include>**</include>
+ </includes>
+ </fileset>
+ </filesets>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <version>1.8</version>
+ <executions>
+ <execution>
+ <id>add-source</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>add-source</goal>
+ </goals>
+ <configuration>
+ <sources>
+ <source>${jmxGeneratorPath}</source>
+ <source>${salGeneratorPath}</source>
+ <source>${xtend.dstdir}</source>
+ </sources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
</plugins>
</pluginManagement>
</build>
<maven>3.0.4</maven>
</prerequisites>
- <properties>
- <jmxGeneratorPath>${project.build.directory}/generated-sources/config</jmxGeneratorPath>
- <salGeneratorPath>${project.build.directory}/generated-sources/sal</salGeneratorPath>
- </properties>
-
<dependencies>
<dependency>
<groupId>io.netty</groupId>
<packaging>bundle</packaging>
<properties>
- <jmxGeneratorPath>${project.build.directory}/generated-sources/config</jmxGeneratorPath>
- <salGeneratorPath>${project.build.directory}/generated-sources/sal</salGeneratorPath>
<config.version>${config-api-version}</config.version>
<yangtools.version>${yang-maven-plugin-version}</yangtools.version>
<maven.bundle.version>${maven-bundle-plugin-version}</maven.bundle.version>
</dependencies>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <version>1.8</version>
- <executions>
- <execution>
- <id>add-source</id>
- <phase>generate-sources</phase>
- <goals>
- <goal>add-source</goal>
- </goals>
- <configuration>
- <sources>
- <source>${jmxGeneratorPath}</source>
- </sources>
- </configuration>
- </execution>
- </executions>
- </plugin>
-
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<maven>3.0.4</maven>
</prerequisites>
- <properties>
- <jmxGeneratorPath>${project.build.directory}/generated-sources/config</jmxGeneratorPath>
- </properties>
-
<build>
<pluginManagement>
<plugins>
</dependency>
</dependencies>
</plugin>
-
- <!-- tell eclipse about generated source folders -->
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <version>1.8</version>
- <executions>
- <execution>
- <id>add-source</id>
- <phase>generate-sources</phase>
- <goals>
- <goal>add-source</goal>
- </goals>
- <configuration>
- <sources>
- <source>${jmxGeneratorPath}</source>
- <source>${salGeneratorPath}</source>
- </sources>
- </configuration>
- </execution>
- </executions>
- </plugin>
</plugins>
</pluginManagement>
</build>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-maven-plugin</artifactId>
</plugin>
+
</plugins>
</build>
</project>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-maven-plugin</artifactId>
</plugin>
-
-
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<osgi.version>5.0.0</osgi.version>
<jacoco.version>0.6.2.201302030002</jacoco.version>
<slf4j.version>1.7.2</slf4j.version>
- <salGeneratorPath>${project.build.directory}/generated-sources/sal</salGeneratorPath>
</properties>
<dependencies>
</dependency>
</dependencies>
</plugin>
- <!-- tell eclipse about generated source folders -->
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <version>1.8</version>
- <executions>
- <execution>
- <id>add-source</id>
- <phase>generate-sources</phase>
- <goals>
- <goal>add-source</goal>
- </goals>
- <configuration>
- <sources>
- <source>${salGeneratorPath}</source>
- </sources>
- </configuration>
- </execution>
- </executions>
- </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
usage
fi
-if [ "${jvmMaxMemory}"=="" ]; then
+if [ "${jvmMaxMemory}" == "" ]; then
jvmMaxMemory="-Xmx1G"
echo "*****************************************************************"
echo "JVM maximum memory was not defined. Setting maximum memory to 1G."
</scm>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<build>
*/
public Status addStaticFlow(FlowConfig config);
+ /**
+ * Add a flow specified by the {@code FlowConfig} object on the current
+ * container, through an asynchronous call.
+ *
+ * @param config
+ * the {@code FlowConfig} object representing the static flow
+ * @return the {@code Status} object indicating the result of this action.
+ */
+ public Status addStaticFlowAsync(FlowConfig config);
+
/**
* Remove a flow specified by the {@code FlowConfig} object on the current
* container
*/
public Status removeStaticFlow(FlowConfig config);
+ /**
+ * Remove a flow specified by the {@code FlowConfig} object on the current
+ * container, through an asynchronous call.
+ *
+ * @param config
+ * the {@code FlowConfig} object representing the static flow
+ * @return the {@code Status} object indicating the result of this action
+ */
+ public Status removeStaticFlowAsync(FlowConfig config);
+
/**
* Replace the flow identified by the {@code FlowConfig.name} name for the
* {@code FlowConfig.node} network node with the new flow specified by
*
* @param config
* the {@code FlowConfig} object
- * @returnthe {@code Status} object indicating the result of this action
+ * @return the {@code Status} object indicating the result of this action
*/
public Status modifyStaticFlow(FlowConfig config);
*/
public Status removeStaticFlow(String name, Node node);
+ /**
+ * Remove the flow specified by name on the passed network node via an
+ * asynchronous call
+ *
+ * @param name
+ * for the static flow
+ * @param node
+ * on which the flow is attached
+ * @return the {@code Status} object indicating the result of this action
+ */
+ public Status removeStaticFlowAsync(String name, Node node);
+
/**
* Toggle the installation status of the specified configured flow If the
* flow configuration status is active, this call will change the flow
@Override
public Status addStaticFlow(FlowConfig config) {
+ return addStaticFlow(config, false);
+ }
+
+ private Status addStaticFlow(FlowConfig config, boolean async) {
// Configuration object validation
Status status = config.validate();
if (!status.isSuccess()) {
config.setStatus(error);
return new Status(StatusCode.BADREQUEST, error);
}
- return addStaticFlowInternal(config, false);
+ return addStaticFlowInternal(config, async, false);
+ }
+
+
+ @Override
+ public Status addStaticFlowAsync(FlowConfig config) {
+ return addStaticFlow(config, true);
}
/**
* installation on the network node was successful
* @return The status of this request
*/
- private Status addStaticFlowInternal(FlowConfig config, boolean restore) {
+ private Status addStaticFlowInternal(FlowConfig config, boolean async, boolean restore) {
boolean multipleFlowPush = false;
String error;
Status status;
// Program hw
if (config.installInHw()) {
FlowEntry entry = config.getFlowEntry();
- status = this.installFlowEntry(entry);
+ status = async ? this.installFlowEntryAsync(entry) : this.installFlowEntry(entry);
if (!status.isSuccess()) {
config.setStatus(status.getDescription());
if (!restore) {
@Override
public Status removeStaticFlow(FlowConfig config) {
+ return removeStaticFlow(config, false);
+ }
+
+ @Override
+ public Status removeStaticFlowAsync(FlowConfig config) {
+ return removeStaticFlow(config, true);
+ }
+
+ private Status removeStaticFlow(FlowConfig config, boolean async) {
/*
* No config.isInternal() check as NB does not take this path and GUI
* cannot issue a delete on an internal generated flow. We need this
}
// Program the network node
- Status status = this.uninstallFlowEntry(config.getFlowEntry());
+ Status status = async ? this.uninstallFlowEntryAsync(config.getFlowEntry()) : this.uninstallFlowEntry(config
+ .getFlowEntry());
// Update configuration database if programming was successful
if (status.isSuccess()) {
@Override
public Status removeStaticFlow(String name, Node node) {
+ return removeStaticFlow(name, node, false);
+ }
+
+ @Override
+ public Status removeStaticFlowAsync(String name, Node node) {
+ return removeStaticFlow(name, node, true);
+ }
+
+ private Status removeStaticFlow(String name, Node node, boolean async) {
// Look for the target configuration entry
Integer key = 0;
FlowConfig target = null;
}
// Program the network node
- Status status = this.removeEntry(target.getFlowEntry(), false);
+ Status status = this.removeEntry(target.getFlowEntry(), async);
// Update configuration database if programming was successful
if (status.isSuccess()) {
}
for (ConfigurationObject conf : configurationService.retrieveConfiguration(this, STATIC_FLOWS_FILE_NAME)) {
- addStaticFlowInternal((FlowConfig) conf, true);
+ addStaticFlowInternal((FlowConfig) conf, false, true);
}
}
// check if the frm really needs to act on the notification.
// this is to check against duplicate notifications
if(programInternalFlow(proactive, fc)) {
- Status status = (proactive) ? addStaticFlowInternal(fc, false) : removeStaticFlow(fc);
+ Status status = (proactive) ? addStaticFlowInternal(fc, false, false) : removeStaticFlow(fc);
if (status.isSuccess()) {
log.trace("{} Proactive Static flow: {}", (proactive ? "Installed" : "Removed"), fc.getName());
} else {
if ((staticFlow.getNode().equals(node)) && (staticFlow.getPortGroup().equals(config.getName()))) {
for (Short port : data.getPorts()) {
FlowConfig derivedFlow = getDerivedFlowConfig(staticFlow, config.getName(), port);
- addStaticFlowInternal(derivedFlow, false);
+ addStaticFlowInternal(derivedFlow, false, false);
}
}
}
}
return list;
}
+
}
<groupId>org.eclipse.xtend</groupId>
<artifactId>xtend-maven-plugin</artifactId>
</plugin>
- <plugin>
- <artifactId>maven-clean-plugin</artifactId>
- </plugin>
</plugins>
</build>
<groupId>org.eclipse.xtend</groupId>
<artifactId>xtend-maven-plugin</artifactId>
</plugin>
- <plugin>
- <artifactId>maven-clean-plugin</artifactId>
- </plugin>
</plugins>
</build>
<groupId>org.eclipse.xtend</groupId>
<artifactId>xtend-maven-plugin</artifactId>
</plugin>
- <plugin>
- <artifactId>maven-clean-plugin</artifactId>
- </plugin>
</plugins>
</build>
<groupId>org.eclipse.xtend</groupId>
<artifactId>xtend-maven-plugin</artifactId>
</plugin>
- <plugin>
- <artifactId>maven-clean-plugin</artifactId>
- </plugin>
</plugins>
</build>
</project>
</dependency>
</dependencies>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <version>1.7</version>
- <executions>
- <execution>
- <phase>generate-sources</phase>
- <goals>
- <goal>add-source</goal>
- </goals>
- <configuration>
- <sources>
- <source>target/generated-sources/sal</source>
- </sources>
- </configuration>
- </execution>
- </executions>
- </plugin>
</plugins>
</build>
<!--module>test/sal-rest-connector-it</modulei -->
</modules>
</profile>
- <profile>
- <id>IDE</id>
- <activation>
- <property>
- <name>m2e.version</name>
- </property>
- </activation>
- <build>
- <!-- Put the IDE's build output in a folder other than target,
- so that IDE builds don't interact with Maven builds -->
- <directory>target-ide</directory>
- </build>
- </profile>
</profiles>
<properties>
- <salGeneratorPath>${project.build.directory}/generated-sources/sal</salGeneratorPath>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- Plugin Versions -->
<groupId>org.eclipse.xtend</groupId>
<artifactId>xtend-maven-plugin</artifactId>
<version>${xtend.version}</version>
- <executions>
- <execution>
- <goals>
- <goal>compile</goal>
- </goals>
- <configuration>
- <outputDirectory>${basedir}/src/main/xtend-gen</outputDirectory>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <artifactId>maven-clean-plugin</artifactId>
- <version>${maven.clean.plugin.version}</version>
- <configuration>
- <filesets>
- <fileset>
- <directory>${basedir}/src/main/xtend-gen</directory>
- <includes>
- <include>**</include>
- </includes>
- </fileset>
- </filesets>
- </configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <version>1.8</version>
- <executions>
- <execution>
- <id>add-source</id>
- <phase>generate-sources</phase>
- <goals>
- <goal>add-source</goal>
- </goals>
- <configuration>
- <sources>
- <source>${project.build.directory}/generated-sources/config</source>
- <source>${project.build.directory}/generated-sources/sal</source>
- <source>src/main/xtend-gen</source>
- </sources>
- </configuration>
- </execution>
- </executions>
- </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<codeGeneratorClass>
org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
</codeGeneratorClass>
- <outputBaseDir>${project.build.directory}/generated-sources/config</outputBaseDir>
+ <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
<additionalConfiguration>
<namespaceToPackage1>
urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang
</dependencies>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <version>1.8</version>
- <executions>
- <execution>
- <id>add-source</id>
- <phase>generate-sources</phase>
- <goals>
- <goal>add-source</goal>
-
-
- </goals>
- <configuration>
- <sources>
- <source>${project.build.directory}/generated-sources/config</source>
- <source>src/main/xtend-gen</source>
- </sources>
- </configuration>
- </execution>
- </executions>
- </plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<groupId>org.eclipse.xtend</groupId>
<artifactId>xtend-maven-plugin</artifactId>
</plugin>
- <plugin>
- <artifactId>maven-clean-plugin</artifactId>
- </plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationException;
import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationOperation;
import org.opendaylight.controller.md.sal.dom.api.DOMDataReadTransaction;
import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
.toNormalizedNode(path, data);
org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalizedPath = normalized.getKey();
- try {
- List<PathArgument> currentArguments = new ArrayList<>();
- DataNormalizationOperation<?> currentOp = codec.getDataNormalizer().getRootOperation();
- Iterator<PathArgument> iterator = normalizedPath.getPath().iterator();
- while (iterator.hasNext()) {
- PathArgument currentArg = iterator.next();
+ List<PathArgument> currentArguments = new ArrayList<>();
+ DataNormalizationOperation<?> currentOp = codec.getDataNormalizer().getRootOperation();
+ Iterator<PathArgument> iterator = normalizedPath.getPath().iterator();
+ while (iterator.hasNext()) {
+ PathArgument currentArg = iterator.next();
+ try {
currentOp = currentOp.getChild(currentArg);
- currentArguments.add(currentArg);
- org.opendaylight.yangtools.yang.data.api.InstanceIdentifier currentPath = new org.opendaylight.yangtools.yang.data.api.InstanceIdentifier(
- currentArguments);
- boolean isPresent = writeTransaction.read(store, currentPath).get().isPresent();
- if (isPresent == false && iterator.hasNext()) {
- writeTransaction.put(store, currentPath, currentOp.createDefault(currentArg));
- }
+ } catch (DataNormalizationException e) {
+ throw new IllegalArgumentException(String.format("Invalid child encountered in path %s", path), e);
+ }
+ currentArguments.add(currentArg);
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier currentPath = new org.opendaylight.yangtools.yang.data.api.InstanceIdentifier(
+ currentArguments);
+
+ final Optional<NormalizedNode<?, ?>> d;
+ try {
+ d = writeTransaction.read(store, currentPath).get();
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.error("Failed to read pre-existing data from store {} path {}", store, currentPath, e);
+ throw new IllegalStateException("Failed to read pre-existing data", e);
+ }
+
+ if (!d.isPresent() && iterator.hasNext()) {
+ writeTransaction.put(store, currentPath, currentOp.createDefault(currentArg));
}
- } catch (InterruptedException | ExecutionException e) {
- e.printStackTrace();
}
//LOG .info("Tx: {} : Putting data {}",getDelegate().getIdentifier(),normalized.getKey());
writeTransaction.put(store, normalized.getKey(), normalized.getValue());
-
}
protected void doMerge(final DOMDataWriteTransaction writeTransaction, final LogicalDatastoreType store,
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.controller.sal.binding.impl;\r
-\r
+package org.opendaylight.controller.sal.binding.impl;
+
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
+import org.opendaylight.controller.md.sal.common.api.data.DataReader;
+import org.opendaylight.controller.md.sal.common.impl.routing.AbstractDataReadRouter;
import org.opendaylight.controller.md.sal.common.impl.service.AbstractDataBroker;
import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
-import org.opendaylight.controller.sal.binding.impl.util.BindingAwareDataReaderRouter;
+import org.opendaylight.yangtools.concepts.Registration;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.util.DataObjectReadingUtil;
import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
import com.google.common.collect.Maps;
-\r
-\r
-public class DataBrokerImpl extends AbstractDataBroker<InstanceIdentifier<? extends DataObject>, DataObject, DataChangeListener> //\r
- implements DataProviderService, AutoCloseable {\r
-\r
+
+public class DataBrokerImpl extends
+ AbstractDataBroker<InstanceIdentifier<? extends DataObject>, DataObject, DataChangeListener> //
+ implements DataProviderService, AutoCloseable {
+
private final static class ContainsWildcarded implements Predicate<InstanceIdentifier<? extends DataObject>> {
- private final InstanceIdentifier<? extends DataObject> key;
+ private final InstanceIdentifier<? extends DataObject> key;
- public ContainsWildcarded(InstanceIdentifier<? extends DataObject> key) {
+ public ContainsWildcarded(final InstanceIdentifier<? extends DataObject> key) {
this.key = key;
}
@Override
- public boolean apply(InstanceIdentifier<? extends DataObject> input) {
+ public boolean apply(final InstanceIdentifier<? extends DataObject> input) {
return key.containsWildcarded(input);
}
}
private final static class IsContainedWildcarded implements Predicate<InstanceIdentifier<? extends DataObject>> {
- private final InstanceIdentifier<? extends DataObject> key;
+ private final InstanceIdentifier<? extends DataObject> key;
- public IsContainedWildcarded(InstanceIdentifier<? extends DataObject> key) {
+ public IsContainedWildcarded(final InstanceIdentifier<? extends DataObject> key) {
this.key = key;
}
@Override
- public boolean apply(InstanceIdentifier<? extends DataObject> input) {
+ public boolean apply(final InstanceIdentifier<? extends DataObject> input) {
return input.containsWildcarded(key);
}
}
- private final AtomicLong nextTransaction = new AtomicLong();\r
- private final AtomicLong createdTransactionsCount = new AtomicLong();\r
-\r
- public AtomicLong getCreatedTransactionsCount() {\r
- return createdTransactionsCount;\r
- }\r
-\r
- public DataBrokerImpl() {\r
- setDataReadRouter(new BindingAwareDataReaderRouter());\r
- }\r
-\r
- @Override\r
- public DataTransactionImpl beginTransaction() {\r
- String transactionId = "BA-" + nextTransaction.getAndIncrement();\r
- createdTransactionsCount.getAndIncrement();\r
- return new DataTransactionImpl(transactionId,this);\r
- }\r
-\r
- @Override\r
- public void close() {\r
-\r
+ private final AtomicLong nextTransaction = new AtomicLong();
+ private final AtomicLong createdTransactionsCount = new AtomicLong();
+ private final DelegatingDataReadRouter router = new DelegatingDataReadRouter();
+ private DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> rootCommitHandler;
+
+ public DataBrokerImpl() {
+ setDataReadRouter(router);
+ }
+
+ public void setDataReadDelegate(final DataReader<InstanceIdentifier<? extends DataObject>, DataObject> delegate) {
+ router.setDelegate(delegate);
+ }
+
+ public AtomicLong getCreatedTransactionsCount() {
+ return createdTransactionsCount;
+ }
+
+ @Override
+ public DataTransactionImpl beginTransaction() {
+ String transactionId = "BA-" + nextTransaction.getAndIncrement();
+ createdTransactionsCount.getAndIncrement();
+ return new DataTransactionImpl(transactionId, this);
}
@Override
- protected Predicate<InstanceIdentifier<? extends DataObject>> createContainsPredicate(final
- InstanceIdentifier<? extends DataObject> key) {
+ public void close() {
+
+ }
+
+ @Override
+ protected Predicate<InstanceIdentifier<? extends DataObject>> createContainsPredicate(
+ final InstanceIdentifier<? extends DataObject> key) {
return new ContainsWildcarded(key);
}
@Override
- protected Predicate<InstanceIdentifier<? extends DataObject>> createIsContainedPredicate(final
- InstanceIdentifier<? extends DataObject> key) {
+ protected Predicate<InstanceIdentifier<? extends DataObject>> createIsContainedPredicate(
+ final InstanceIdentifier<? extends DataObject> key) {
return new IsContainedWildcarded(key);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
protected Map<InstanceIdentifier<? extends DataObject>, DataObject> deepGetBySubpath(
- Map<InstanceIdentifier<? extends DataObject>, DataObject> dataSet,
- InstanceIdentifier<? extends DataObject> path) {
+ final Map<InstanceIdentifier<? extends DataObject>, DataObject> dataSet,
+ final InstanceIdentifier<? extends DataObject> path) {
Builder<InstanceIdentifier<? extends DataObject>, DataObject> builder = ImmutableMap.builder();
- Map<InstanceIdentifier<? extends DataObject>, DataObject> potential = Maps.filterKeys(dataSet, createIsContainedPredicate(path));
- for(Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry : potential.entrySet()) {
+ Map<InstanceIdentifier<? extends DataObject>, DataObject> potential = Maps.filterKeys(dataSet,
+ createIsContainedPredicate(path));
+ for (Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry : potential.entrySet()) {
try {
- builder.putAll(DataObjectReadingUtil.readData(entry.getValue(),(InstanceIdentifier)entry.getKey(),path));
+ builder.putAll(DataObjectReadingUtil.readData(entry.getValue(), (InstanceIdentifier) entry.getKey(),
+ path));
} catch (Exception e) {
// FIXME : Log exception;
}
return builder.build();
}
-\r
+
+ public class DelegatingDataReadRouter extends
+ AbstractDataReadRouter<InstanceIdentifier<? extends DataObject>, DataObject> {
+
+ private DataReader<InstanceIdentifier<? extends DataObject>, DataObject> delegate;
+
+ @Override
+ public DataObject readConfigurationData(final InstanceIdentifier<? extends DataObject> path) {
+ return delegate.readConfigurationData(path);
+ }
+
+ public void setDelegate(final DataReader<InstanceIdentifier<? extends DataObject>, DataObject> delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override
+ public DataObject readOperationalData(final InstanceIdentifier<? extends DataObject> path) {
+ return delegate.readOperationalData(path);
+ }
+
+ @Override
+ protected DataObject merge(final InstanceIdentifier<? extends DataObject> path, final Iterable<DataObject> data) {
+ throw new UnsupportedOperationException("Not supported");
+ }
+
+ @Override
+ public Registration<DataReader<InstanceIdentifier<? extends DataObject>, DataObject>> registerConfigurationReader(
+ final InstanceIdentifier<? extends DataObject> path,
+ final DataReader<InstanceIdentifier<? extends DataObject>, DataObject> reader) {
+ throw new UnsupportedOperationException("Not supported");
+ }
+
+ @Override
+ public Registration<DataReader<InstanceIdentifier<? extends DataObject>, DataObject>> registerOperationalReader(
+ final InstanceIdentifier<? extends DataObject> path,
+ final DataReader<InstanceIdentifier<? extends DataObject>, DataObject> reader) {
+ throw new UnsupportedOperationException("Not supported");
+ }
+ }
+
+ @Override
+ protected ImmutableList<DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject>> affectedCommitHandlers(
+ final Set<InstanceIdentifier<? extends DataObject>> paths) {
+ ImmutableList.Builder<DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject>> handlersBuilder = ImmutableList.builder();
+ return handlersBuilder //
+ .add(rootCommitHandler) //
+ .addAll(super.affectedCommitHandlers(paths)) //
+ .build();
+ }
+
+ public void setRootCommitHandler(final DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> commitHandler) {
+ rootCommitHandler = commitHandler;
+ }
+
}
super(rpcRegistry, notificationBroker, dataBroker);
this.identifier = identifier;
}
+
+ // Needed only for BI Connector
+ public DataBrokerImpl getDataBrokerImpl() {
+ return (DataBrokerImpl) getDataBroker();
+ }
@Override
public InstanceIdentifier<?> getIdentifier() {
override publish(Notification notification, ExecutorService service) {\r
val allTypes = notification.notificationTypes\r
\r
- var Iterable<NotificationListener<?>> listenerToNotify = Collections.emptySet();\r
+ var Iterable<NotificationListener<? extends Object>> listenerToNotify = Collections.emptySet();\r
for (type : allTypes) {\r
listenerToNotify = listenerToNotify + listeners.get(type as Class<? extends Notification>)\r
}\r
import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction;
import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandlerRegistration;
import org.opendaylight.controller.md.sal.common.api.data.DataModification;
-import org.opendaylight.controller.md.sal.common.api.data.DataReader;
import org.opendaylight.controller.md.sal.common.api.routing.RouteChange;
import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener;
import org.opendaylight.controller.md.sal.common.api.routing.RouteChangePublisher;
import org.opendaylight.controller.sal.binding.api.data.RuntimeDataProvider;
import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier;
import org.opendaylight.controller.sal.binding.api.rpc.RpcRouter;
+import org.opendaylight.controller.sal.binding.impl.DataBrokerImpl;
+import org.opendaylight.controller.sal.binding.impl.MountPointManagerImpl.BindingMountPointImpl;
import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl;
import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl.GlobalRpcRegistrationListener;
import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl.RouterInstantiationListener;
private final Logger LOG = LoggerFactory.getLogger(BindingIndependentConnector.class);
- @SuppressWarnings("deprecation")
- private static final InstanceIdentifier<? extends DataObject> ROOT = InstanceIdentifier.builder().toInstance();
private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier ROOT_BI = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
.builder().toInstance();
};
- private Registration<DataReader<InstanceIdentifier<? extends DataObject>, DataObject>> baDataReaderRegistration;
-
private boolean rpcForwarding = false;
private boolean dataForwarding = false;
dataForwarding = true;
return;
}
- checkState(!dataForwarding, "Connector is already forwarding data.");
- baDataReaderRegistration = baDataService.registerDataReader(ROOT, this);
- baCommitHandlerRegistration = baDataService.registerCommitHandler(ROOT, bindingToDomCommitHandler);
- biCommitHandlerRegistration = biDataService.registerCommitHandler(ROOT_BI, domToBindingCommitHandler);
- baDataService.registerCommitHandlerListener(domToBindingCommitHandler);
+
+ final DataProviderService baData;
+ if (baDataService instanceof BindingMountPointImpl) {
+ baData = ((BindingMountPointImpl)baDataService).getDataBrokerImpl();
+ LOG.debug("Extracted BA Data provider {} from mount point {}", baData, baDataService);
+ } else {
+ baData = baDataService;
+ }
+
+ if (baData instanceof DataBrokerImpl) {
+ checkState(!dataForwarding, "Connector is already forwarding data.");
+ ((DataBrokerImpl) baData).setDataReadDelegate(this);
+ ((DataBrokerImpl) baData).setRootCommitHandler(bindingToDomCommitHandler);
+ biCommitHandlerRegistration = biDataService.registerCommitHandler(ROOT_BI, domToBindingCommitHandler);
+ baDataService.registerCommitHandlerListener(domToBindingCommitHandler);
+ }
+
dataForwarding = true;
}
import static org.mockito.Mockito.verify;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
import javassist.ClassPool;
import org.opendaylight.yangtools.yang.binding.DataContainer;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
public class RuntimeCodeGeneratorTest {
}
- private void verifyRouting(RpcRouter<FooService> product) {
+ private void verifyRouting(final RpcRouter<FooService> product) {
assertNotNull("Routing table should be initialized", product.getRoutingTable(BaseIdentity.class));
RpcRoutingTable<BaseIdentity, FooService> routingTable = product.getRoutingTable(BaseIdentity.class);
verify(service[1]).simple(instance_1_input[0]);
}
- private InstanceIdentifier<?>[][] identifiers(int serviceSize, int instancesPerService) {
+ private InstanceIdentifier<?>[][] identifiers(final int serviceSize, final int instancesPerService) {
InstanceIdentifier<?>[][] ret = new InstanceIdentifier[serviceSize][];
int service = 0;
for (int i = 0; i < serviceSize; i++) {
return ret;
}
- private InstanceIdentifier<?> referencableIdentifier(int i) {
- ReferencableObjectKey key = new ReferencableObjectKey(i);
- IdentifiableItem<ReferencableObject, ReferencableObjectKey> pathArg = new IdentifiableItem<>(
- ReferencableObject.class, key);
- return new InstanceIdentifier<ReferencableObject>(Arrays.<PathArgument> asList(pathArg),
- ReferencableObject.class);
+ private InstanceIdentifier<?> referencableIdentifier(final int i) {
+ return InstanceIdentifier.builder(ReferencableObject.class, new ReferencableObjectKey(i)).build();
}
private static class SimpleInputImpl implements SimpleInput {
private final InstanceIdentifier<?> identifier;
- public SimpleInputImpl(InstanceIdentifier<?> _identifier) {
+ public SimpleInputImpl(final InstanceIdentifier<?> _identifier) {
this.identifier = _identifier;
}
@Override
- public <E extends Augmentation<SimpleInput>> E getAugmentation(Class<E> augmentationType) {
+ public <E extends Augmentation<SimpleInput>> E getAugmentation(final Class<E> augmentationType) {
return null;
}
List<FooUpdate> receivedFoos = new ArrayList<>();
@Override
- public void onFooUpdate(FooUpdate notification) {
+ public void onFooUpdate(final FooUpdate notification) {
receivedFoos.add(notification);
}
List<FlowDelete> receivedDeletes = new ArrayList<>();
@Override
- public void onBarUpdate(BarUpdate notification) {
+ public void onBarUpdate(final BarUpdate notification) {
receivedBars.add(notification);
}
@Override
- public void onFlowDelete(FlowDelete notification) {
+ public void onFlowDelete(final FlowDelete notification) {
receivedDeletes.add(notification);
}
*/
package org.opendaylight.controller.sal.binding.test.mock;
+import org.opendaylight.yangtools.yang.binding.ChildOf;
import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.DataRoot;
import org.opendaylight.yangtools.yang.binding.Identifiable;
-public interface ReferencableObject extends DataObject,Identifiable<ReferencableObjectKey> {
+public interface ReferencableObject extends DataObject,
+ Identifiable<ReferencableObjectKey>,ChildOf<DataRoot>{
}
<codeGeneratorClass>
org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
</codeGeneratorClass>
- <outputBaseDir>${project.build.directory}/generated-sources/config</outputBaseDir>
+ <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
<additionalConfiguration>
<namespaceToPackage1>
urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang
</dependency>
</dependencies>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <version>1.8</version>
- <executions>
- <execution>
- <id>add-source</id>
- <phase>generate-sources</phase>
- <goals>
- <goal>add-source</goal>
- </goals>
- <configuration>
- <sources>
- <source>${project.build.directory}/generated-sources/config</source>
- </sources>
- </configuration>
- </execution>
- </executions>
- </plugin>
</plugins>
</build>
<groupId>org.eclipse.xtend</groupId>
<artifactId>xtend-maven-plugin</artifactId>
</plugin>
- <plugin>
- <artifactId>maven-clean-plugin</artifactId>
- </plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.common.impl.util.compat;
+
+public class DataNormalizationException extends Exception {
+ private static final long serialVersionUID = 1L;
+
+ public DataNormalizationException(String message) {
+ super(message);
+ }
+
+ public DataNormalizationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
package org.opendaylight.controller.md.sal.common.impl.util.compat;
import static com.google.common.base.Preconditions.checkArgument;
return Collections.singleton(identifier.getNodeType());
}
- public abstract DataNormalizationOperation<?> getChild(final PathArgument child);
+ public abstract DataNormalizationOperation<?> getChild(final PathArgument child) throws DataNormalizationException;
- public abstract DataNormalizationOperation<?> getChild(QName child);
+ public abstract DataNormalizationOperation<?> getChild(QName child) throws DataNormalizationException;
public abstract NormalizedNode<?, ?> normalize(Node<?> legacyData);
Set<DataNormalizationOperation<?>> usedMixins = new HashSet<>();
for (Node<?> childLegacy : compositeNode.getValue()) {
- DataNormalizationOperation childOp = getChild(childLegacy.getNodeType());
+ final DataNormalizationOperation childOp;
+
+ try {
+ childOp = getChild(childLegacy.getNodeType());
+ } catch (DataNormalizationException e) {
+ throw new IllegalArgumentException(String.format("Failed to normalize data %s", compositeNode.getValue()), e);
+ }
// We skip unknown nodes if this node is mixin since
// it's nodes and parent nodes are interleaved
if (childOp.isMixin()) {
if (usedMixins.contains(childOp)) {
// We already run / processed that mixin, so to avoid
- // dupliciry we are
- // skiping next nodes.
+ // duplicity we are skipping next nodes.
continue;
}
builder.addChild(childOp.normalize(compositeNode));
}
@Override
- public DataNormalizationOperation<?> getChild(final PathArgument child) {
+ public DataNormalizationOperation<?> getChild(final PathArgument child) throws DataNormalizationException {
DataNormalizationOperation<?> potential = byArg.get(child);
if (potential != null) {
return potential;
}
@Override
- public DataNormalizationOperation<?> getChild(final QName child) {
+ public DataNormalizationOperation<?> getChild(final QName child) throws DataNormalizationException {
DataNormalizationOperation<?> potential = byQName.get(child);
if (potential != null) {
return potential;
}
}
- public static DataNormalizationOperation<?> fromSchemaAndPathArgument(final DataNodeContainer schema,
- final QName child) {
+ private static DataNormalizationOperation<?> fromSchemaAndPathArgument(final DataNodeContainer schema,
+ final QName child) throws DataNormalizationException {
DataSchemaNode potential = schema.getDataChildByName(child);
if (potential == null) {
Iterable<org.opendaylight.yangtools.yang.model.api.ChoiceNode> choices = FluentIterable.from(
schema.getChildNodes()).filter(org.opendaylight.yangtools.yang.model.api.ChoiceNode.class);
potential = findChoice(choices, child);
}
- checkArgument(potential != null, "Supplied QName %s is not valid according to schema %s", child, schema);
+
+ if (potential == null) {
+ throw new DataNormalizationException(String.format("Supplied QName %s is not valid according to schema %s", child, schema));
+ }
+
if ((schema instanceof DataSchemaNode) && !((DataSchemaNode) schema).isAugmenting() && potential.isAugmenting()) {
return fromAugmentation(schema, (AugmentationTarget) schema, potential);
}
}
}
- private static DataNormalizationOperation<?> fromSchema(final DataNodeContainer schema, final PathArgument child) {
+ private static DataNormalizationOperation<?> fromSchema(final DataNodeContainer schema, final PathArgument child) throws DataNormalizationException {
if (child instanceof AugmentationIdentifier) {
return fromSchemaAndPathArgument(schema, ((AugmentationIdentifier) child).getPossibleChildNames()
.iterator().next());
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
package org.opendaylight.controller.md.sal.common.impl.util.compat;
import static com.google.common.base.Preconditions.checkArgument;
import java.util.Iterator;
import java.util.Map;
+import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.AugmentationIdentifier;
DataNormalizationOperation<?> currentOp = operation;
Iterator<PathArgument> arguments = legacy.getPath().iterator();
- while ( arguments.hasNext() ) {
- PathArgument legacyArg = arguments.next();
- currentOp = currentOp.getChild(legacyArg);
- checkArgument(currentOp != null, "Legacy Instance Identifier %s is not correct. Normalized Instance Identifier so far %s",legacy,normalizedArgs.build());
- while (currentOp.isMixin()) {
- normalizedArgs.add(currentOp.getIdentifier());
- currentOp = currentOp.getChild(legacyArg.getNodeType());
- }
- if(arguments.hasNext() || (!currentOp.isKeyedEntry() || legacyArg instanceof NodeIdentifierWithPredicates || legacyArg instanceof NodeWithValue)) {
- normalizedArgs.add(legacyArg);
+
+ try {
+ while ( arguments.hasNext() ) {
+ PathArgument legacyArg = arguments.next();
+ currentOp = currentOp.getChild(legacyArg);
+ checkArgument(currentOp != null, "Legacy Instance Identifier %s is not correct. Normalized Instance Identifier so far %s",legacy,normalizedArgs.build());
+ while (currentOp.isMixin()) {
+ normalizedArgs.add(currentOp.getIdentifier());
+ currentOp = currentOp.getChild(legacyArg.getNodeType());
+ }
+ if(arguments.hasNext() || (!currentOp.isKeyedEntry() || legacyArg instanceof NodeIdentifierWithPredicates || legacyArg instanceof NodeWithValue)) {
+ normalizedArgs.add(legacyArg);
+ }
}
+ } catch (DataNormalizationException e) {
+ throw new IllegalArgumentException(String.format("Failed to normalize path %s", legacy), e);
}
+
return new InstanceIdentifier(normalizedArgs.build());
}
DataNormalizationOperation<?> currentOp = operation;
for (PathArgument arg : normalizedPath.getPath()) {
- currentOp = currentOp.getChild(arg);
+ try {
+ currentOp = currentOp.getChild(arg);
+ } catch (DataNormalizationException e) {
+ throw new IllegalArgumentException(String.format("Failed to validate normalized path %s", normalizedPath), e);
+ }
}
- // Write Augmentaiton data resolution
+
+ // Write Augmentation data resolution
if (legacyData.getChildren().size() == 1) {
- DataNormalizationOperation<?> potentialOp = currentOp.getChild(legacyData.getChildren().get(0)
- .getNodeType());
+ final DataNormalizationOperation<?> potentialOp;
+
+ try {
+ final QName childType = legacyData.getChildren().get(0).getNodeType();
+ potentialOp = currentOp.getChild(childType);
+ } catch (DataNormalizationException e) {
+ throw new IllegalArgumentException(String.format("Failed to get child operation for %s", legacyData), e);
+ }
+
if(potentialOp.getIdentifier() instanceof AugmentationIdentifier) {
currentOp = potentialOp;
ArrayList<PathArgument> reworkedArgs = new ArrayList<>(normalizedPath.getPath());
<codeGeneratorClass>
org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
</codeGeneratorClass>
- <outputBaseDir>${project.build.directory}/generated-sources/config</outputBaseDir>
+ <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
<additionalConfiguration>
<namespaceToPackage1>
urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang
</dependency>
</dependencies>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <version>1.8</version>
- <executions>
- <execution>
- <id>add-source</id>
- <phase>generate-sources</phase>
- <goals>
- <goal>add-source</goal>
- </goals>
- <configuration>
- <sources>
- <source>${project.build.directory}/generated-sources/config</source>
- </sources>
- </configuration>
- </execution>
- </executions>
- </plugin>
</plugins>
</build>
<dependencies>
<codeGeneratorClass>
org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
</codeGeneratorClass>
- <outputBaseDir>${project.build.directory}/generated-sources/config</outputBaseDir>
+ <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
<additionalConfiguration>
<namespaceToPackage1>
urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang
</instructions>
</configuration>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <version>1.8</version>
- <executions>
- <execution>
- <id>add-source</id>
- <phase>generate-sources</phase>
- <goals>
- <goal>add-source</goal>
- </goals>
- <configuration>
- <sources>
- <source>${project.build.directory}/generated-sources/config</source>
- <source>src/main/xtend-gen</source>
- </sources>
- </configuration>
- </execution>
- </executions>
- </plugin>
<plugin>
<groupId>org.eclipse.xtend</groupId>
<artifactId>xtend-maven-plugin</artifactId>
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
package org.opendaylight.controller.md.sal.dom.broker.impl.compat;
import static com.google.common.base.Preconditions.checkNotNull;
import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationException;
import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationOperation;
import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizer;
import org.opendaylight.controller.md.sal.dom.api.DOMDataReadTransaction;
Iterator<PathArgument> iterator = normalizedPath.getPath().iterator();
while(iterator.hasNext()) {
PathArgument currentArg = iterator.next();
- currentOp = currentOp.getChild(currentArg);
+ try {
+ currentOp = currentOp.getChild(currentArg);
+ } catch (DataNormalizationException e) {
+ throw new IllegalArgumentException(String.format("Invalid child encountered in path %s", normalizedPath), e);
+ }
currentArguments.add(currentArg);
InstanceIdentifier currentPath = new InstanceIdentifier(currentArguments);
boolean isPresent = getDelegate().read(store, currentPath).get().isPresent();
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
import org.opendaylight.controller.md.sal.dom.store.impl.DOMImmutableDataChangeEvent.Builder;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.ListenerRegistrationNode;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.ListenerTree;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.ListenerTree.Walker;
import org.opendaylight.controller.md.sal.dom.store.impl.tree.NodeModification;
import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreMetadataNode;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
private static final DOMImmutableDataChangeEvent NO_CHANGE = builder().build();
private final ImmutableList.Builder<ChangeListenerNotifyTask> tasks = ImmutableList.builder();
private InstanceIdentifier rootPath;
- private ListenerRegistrationNode listenerRoot;
+ private ListenerTree listenerRoot;
private NodeModification modificationRoot;
private Optional<StoreMetadataNode> beforeRoot;
private Optional<StoreMetadataNode> afterRoot;
return this;
}
- protected ListenerRegistrationNode getListenerRoot() {
+ protected ListenerTree getListenerRoot() {
return listenerRoot;
}
- protected DataChangeEventResolver setListenerRoot(final ListenerRegistrationNode listenerRoot) {
+ protected DataChangeEventResolver setListenerRoot(final ListenerTree listenerRoot) {
this.listenerRoot = listenerRoot;
return this;
}
}
public Iterable<ChangeListenerNotifyTask> resolve() {
- LOG.trace("Resolving events for {}" ,modificationRoot);
- resolveAnyChangeEvent(rootPath, Optional.of(listenerRoot), modificationRoot, beforeRoot, afterRoot);
- return tasks.build();
+ LOG.trace("Resolving events for {}", modificationRoot);
+
+ try (final Walker w = listenerRoot.getWalker()) {
+ resolveAnyChangeEvent(rootPath, Optional.of(w.getRootNode()), modificationRoot, beforeRoot, afterRoot);
+ return tasks.build();
+ }
}
private DOMImmutableDataChangeEvent resolveAnyChangeEvent(final InstanceIdentifier path,
- final Optional<ListenerRegistrationNode> listeners, final NodeModification modification,
+ final Optional<ListenerTree.Node> listeners, final NodeModification modification,
final Optional<StoreMetadataNode> before, final Optional<StoreMetadataNode> after) {
// No listeners are present in listener registration subtree
// no before and after state is present
* @return
*/
private DOMImmutableDataChangeEvent resolveCreateEvent(final InstanceIdentifier path,
- final Optional<ListenerRegistrationNode> listeners, final StoreMetadataNode afterState) {
+ final Optional<ListenerTree.Node> listeners, final StoreMetadataNode afterState) {
final NormalizedNode<?, ?> node = afterState.getData();
Builder builder = builder().setAfter(node).addCreated(path, node);
for (StoreMetadataNode child : afterState.getChildren()) {
PathArgument childId = child.getIdentifier();
- Optional<ListenerRegistrationNode> childListeners = getChild(listeners, childId);
+ Optional<ListenerTree.Node> childListeners = getChild(listeners, childId);
InstanceIdentifier childPath = StoreUtils.append(path, childId);
builder.merge(resolveCreateEvent(childPath, childListeners, child));
}
private DOMImmutableDataChangeEvent resolveDeleteEvent(final InstanceIdentifier path,
- final Optional<ListenerRegistrationNode> listeners, final StoreMetadataNode beforeState) {
+ final Optional<ListenerTree.Node> listeners, final StoreMetadataNode beforeState) {
final NormalizedNode<?, ?> node = beforeState.getData();
Builder builder = builder().setBefore(node).addRemoved(path, node);
for (StoreMetadataNode child : beforeState.getChildren()) {
PathArgument childId = child.getIdentifier();
- Optional<ListenerRegistrationNode> childListeners = getChild(listeners, childId);
+ Optional<ListenerTree.Node> childListeners = getChild(listeners, childId);
InstanceIdentifier childPath = StoreUtils.append(path, childId);
builder.merge(resolveDeleteEvent(childPath, childListeners, child));
}
}
private DOMImmutableDataChangeEvent resolveSubtreeChangeEvent(final InstanceIdentifier path,
- final Optional<ListenerRegistrationNode> listeners, final NodeModification modification,
+ final Optional<ListenerTree.Node> listeners, final NodeModification modification,
final StoreMetadataNode before, final StoreMetadataNode after) {
Builder one = builder().setBefore(before.getData()).setAfter(after.getData());
for (NodeModification childMod : modification.getModifications()) {
PathArgument childId = childMod.getIdentifier();
InstanceIdentifier childPath = append(path, childId);
- Optional<ListenerRegistrationNode> childListen = getChild(listeners, childId);
+ Optional<ListenerTree.Node> childListen = getChild(listeners, childId);
Optional<StoreMetadataNode> childBefore = before.getChild(childId);
Optional<StoreMetadataNode> childAfter = after.getChild(childId);
}
private DOMImmutableDataChangeEvent resolveReplacedEvent(final InstanceIdentifier path,
- final Optional<ListenerRegistrationNode> listeners, final NodeModification modification,
+ final Optional<ListenerTree.Node> listeners, final NodeModification modification,
final StoreMetadataNode before, final StoreMetadataNode after) {
// FIXME Add task
return builder().build();
}
- private DOMImmutableDataChangeEvent addNotifyTask(final Optional<ListenerRegistrationNode> listeners, final DOMImmutableDataChangeEvent event) {
+ private DOMImmutableDataChangeEvent addNotifyTask(final Optional<ListenerTree.Node> listeners, final DOMImmutableDataChangeEvent event) {
if (listeners.isPresent()) {
final Collection<DataChangeListenerRegistration<?>> l = listeners.get().getListeners();
if (!l.isEmpty()) {
return event;
}
- private void addNotifyTask(final ListenerRegistrationNode listenerRegistrationNode, final DataChangeScope scope,
+ private void addNotifyTask(final ListenerTree.Node listenerRegistrationNode, final DataChangeScope scope,
final DOMImmutableDataChangeEvent event) {
Collection<DataChangeListenerRegistration<?>> potential = listenerRegistrationNode.getListeners();
if(!potential.isEmpty()) {
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeListener;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.ListenerRegistrationNode;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.ListenerRegistrationNode.DataChangeListenerRegistration;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.ListenerTree;
import org.opendaylight.controller.md.sal.dom.store.impl.tree.ModificationType;
import org.opendaylight.controller.md.sal.dom.store.impl.tree.NodeModification;
import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreMetadataNode;
private final ListeningExecutorService executor;
private final String name;
private final AtomicLong txCounter = new AtomicLong(0);
- private final ListenerRegistrationNode listenerTree;
+ private final ListenerTree listenerTree;
private final AtomicReference<DataAndMetadataSnapshot> snapshot;
private ModificationApplyOperation operationTree;
public InMemoryDOMDataStore(final String name, final ListeningExecutorService executor) {
this.name = Preconditions.checkNotNull(name);
this.executor = Preconditions.checkNotNull(executor);
- this.listenerTree = ListenerRegistrationNode.createRoot();
+ this.listenerTree = ListenerTree.create();
this.snapshot = new AtomicReference<DataAndMetadataSnapshot>(DataAndMetadataSnapshot.createEmpty());
this.operationTree = new AlwaysFailOperation();
}
final DataChangeListenerRegistration<L> reg;
synchronized (this) {
LOG.debug("{}: Registering data change listener {} for {}",name,listener,path);
- ListenerRegistrationNode listenerNode = listenerTree;
- for(PathArgument arg : path.getPath()) {
- listenerNode = listenerNode.ensureChild(arg);
- }
- reg = listenerNode.registerDataChangeListener(path, listener, scope);
+ reg = listenerTree.registerDataChangeListener(path, listener, scope);
Optional<StoreMetadataNode> currentState = snapshot.get().read(path);
if (currentState.isPresent()) {
+++ /dev/null
-package org.opendaylight.controller.md.sal.dom.store.impl.tree;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeListener;
-import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
-import org.opendaylight.yangtools.concepts.Identifiable;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Optional;
-
-public class ListenerRegistrationNode implements StoreTreeNode<ListenerRegistrationNode>, Identifiable<PathArgument> {
-
- private static final Logger LOG = LoggerFactory.getLogger(ListenerRegistrationNode.class);
-
- private final ListenerRegistrationNode parent;
- private final Map<PathArgument, ListenerRegistrationNode> children;
- private final PathArgument identifier;
- private final HashSet<DataChangeListenerRegistration<?>> listeners;
-
- private ListenerRegistrationNode(final PathArgument identifier) {
- this(null, identifier);
- }
-
- private ListenerRegistrationNode(final ListenerRegistrationNode parent, final PathArgument identifier) {
- this.parent = parent;
- this.identifier = identifier;
- children = new HashMap<>();
- listeners = new HashSet<>();
- }
-
- public final static ListenerRegistrationNode createRoot() {
- return new ListenerRegistrationNode(null);
- }
-
- @Override
- public PathArgument getIdentifier() {
- return identifier;
- }
-
- /**
- * Return the list of current listeners. Any caller wishing to use this method
- * has to make sure the collection remains unchanged while it's executing. This
- * means the caller has to synchronize externally both the registration and
- * unregistration process.
- *
- * @return the list of current listeners
- */
- @SuppressWarnings({ "rawtypes", "unchecked" })
- public Collection<org.opendaylight.controller.md.sal.dom.store.impl.DataChangeListenerRegistration<?>> getListeners() {
- return (Collection) listeners;
- }
-
- @Override
- public synchronized Optional<ListenerRegistrationNode> getChild(final PathArgument child) {
- return Optional.fromNullable(children.get(child));
- }
-
- public synchronized ListenerRegistrationNode ensureChild(final PathArgument child) {
- ListenerRegistrationNode potential = (children.get(child));
- if (potential == null) {
- potential = new ListenerRegistrationNode(this, child);
- children.put(child, potential);
- }
- return potential;
- }
-
- /**
- * Registers listener on this node.
- *
- * @param path Full path on which listener is registered.
- * @param listener Listener
- * @param scope Scope of triggering event.
- * @return
- */
- public synchronized <L extends AsyncDataChangeListener<InstanceIdentifier, NormalizedNode<?, ?>>> DataChangeListenerRegistration<L> registerDataChangeListener(final InstanceIdentifier path,
- final L listener, final DataChangeScope scope) {
-
- DataChangeListenerRegistration<L> listenerReg = new DataChangeListenerRegistration<L>(path,listener, scope, this);
- listeners.add(listenerReg);
- LOG.debug("Listener {} registered", listener);
- return listenerReg;
- }
-
- private synchronized void removeListener(final DataChangeListenerRegistration<?> listener) {
- listeners.remove(listener);
- LOG.debug("Listener {} unregistered", listener);
- removeThisIfUnused();
- }
-
- private void removeThisIfUnused() {
- if (parent != null && listeners.isEmpty() && children.isEmpty()) {
- parent.removeChildIfUnused(this);
- }
- }
-
- public boolean isUnused() {
- return (listeners.isEmpty() && children.isEmpty()) || areChildrenUnused();
- }
-
- private boolean areChildrenUnused() {
- for (ListenerRegistrationNode child : children.values()) {
- if (!child.isUnused()) {
- return false;
- }
- }
- return true;
- }
-
- private void removeChildIfUnused(final ListenerRegistrationNode listenerRegistrationNode) {
- // FIXME Remove unnecessary
- }
-
- public static class DataChangeListenerRegistration<T extends AsyncDataChangeListener<InstanceIdentifier, NormalizedNode<?, ?>>>
- extends AbstractObjectRegistration<T> implements
- org.opendaylight.controller.md.sal.dom.store.impl.DataChangeListenerRegistration<T> {
-
- private final DataChangeScope scope;
- private ListenerRegistrationNode node;
- private final InstanceIdentifier path;
-
- public DataChangeListenerRegistration(final InstanceIdentifier path,final T listener, final DataChangeScope scope,
- final ListenerRegistrationNode node) {
- super(listener);
- this.path = path;
- this.scope = scope;
- this.node = node;
- }
-
- @Override
- public DataChangeScope getScope() {
- return scope;
- }
-
- @Override
- protected void removeRegistration() {
- node.removeListener(this);
- node = null;
- }
-
- @Override
- public InstanceIdentifier getPath() {
- return path;
- }
- }
-}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.dom.store.impl.tree;
+
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import javax.annotation.concurrent.GuardedBy;
+
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeListener;
+import org.opendaylight.controller.md.sal.dom.store.impl.DataChangeListenerRegistration;
+import org.opendaylight.yangtools.concepts.AbstractListenerRegistration;
+import org.opendaylight.yangtools.concepts.Identifiable;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+
+public final class ListenerTree {
+ private static final Logger LOG = LoggerFactory.getLogger(ListenerTree.class);
+ private final ReadWriteLock rwLock = new ReentrantReadWriteLock(true);
+ private final Node rootNode = new Node(null, null);
+
+ private ListenerTree() {
+
+ }
+
+ public static ListenerTree create() {
+ return new ListenerTree();
+ }
+
+ /**
+ * Registers listener on this node.
+ *
+ * @param path Full path on which listener is registered.
+ * @param listener Listener
+ * @param scope Scope of triggering event.
+ * @return Listener registration
+ */
+ public <L extends AsyncDataChangeListener<InstanceIdentifier, NormalizedNode<?, ?>>> DataChangeListenerRegistration<L> registerDataChangeListener(final InstanceIdentifier path,
+ final L listener, final DataChangeScope scope) {
+
+ // Take the write lock
+ rwLock.writeLock().lock();
+
+ try {
+ Node walkNode = rootNode;
+ for (final PathArgument arg : path.getPath()) {
+ walkNode = walkNode.ensureChild(arg);
+ }
+
+ final Node node = walkNode;
+ DataChangeListenerRegistration<L> reg = new DataChangeListenerRegistrationImpl<L>(listener) {
+ @Override
+ public DataChangeScope getScope() {
+ return scope;
+ }
+
+ @Override
+ public InstanceIdentifier getPath() {
+ return path;
+ }
+
+ @Override
+ protected void removeRegistration() {
+ /*
+ * TODO: Here's an interesting problem. The way the datastore works, it
+ * enqueues requests towards the listener, so the listener will be
+ * notified at some point in the future. Now if the registration is
+ * closed, we will prevent any new events from being delivered, but
+ * we have no way to purge that queue.
+ *
+ * While this does not directly violate the ListenerRegistration
+ * contract, it is probably not going to be liked by the users.
+ */
+
+ // Take the write lock
+ ListenerTree.this.rwLock.writeLock().lock();
+ try {
+ node.removeListener(this);
+ } finally {
+ // Always release the lock
+ ListenerTree.this.rwLock.writeLock().unlock();
+ }
+ }
+ };
+
+ node.addListener(reg);
+ return reg;
+ } finally {
+ // Always release the lock
+ rwLock.writeLock().unlock();
+ }
+ }
+
+ public Walker getWalker() {
+ /*
+ * TODO: The only current user of this method is local to the datastore.
+ * Since this class represents a read-lock, losing a reference to
+ * it is a _major_ problem, as the registration process will get
+ * wedged, eventually grinding the system to a halt. Should an
+ * external user exist, make the Walker a phantom reference, which
+ * will cleanup the lock if not told to do so.
+ */
+ final Walker ret = new Walker(rwLock.readLock(), rootNode);
+ rwLock.readLock().lock();
+ return ret;
+ }
+
+ public static final class Walker implements AutoCloseable {
+ private final Lock lock;
+ private final Node node;
+
+ @GuardedBy("this")
+ private boolean valid = true;
+
+ private Walker(final Lock lock, final Node node) {
+ this.lock = Preconditions.checkNotNull(lock);
+ this.node = Preconditions.checkNotNull(node);
+ }
+
+ public Node getRootNode() {
+ return node;
+ }
+
+ @Override
+ public synchronized void close() {
+ if (valid) {
+ lock.unlock();
+ valid = false;
+ }
+ }
+ }
+
+ /**
+ * This is a single node within the listener tree. Note that the data returned from
+ * and instance of this class is guaranteed to have any relevance or consistency
+ * only as long as the {@link Walker} instance through which it is reached remains
+ * unclosed.
+ */
+ public static final class Node implements StoreTreeNode<Node>, Identifiable<PathArgument> {
+ private final Collection<DataChangeListenerRegistration<?>> listeners = new ArrayList<>();
+ private final Map<PathArgument, Node> children = new HashMap<>();
+ private final PathArgument identifier;
+ private final Reference<Node> parent;
+
+ private Node(final Node parent, final PathArgument identifier) {
+ this.parent = new WeakReference<>(parent);
+ this.identifier = identifier;
+ }
+
+ @Override
+ public PathArgument getIdentifier() {
+ return identifier;
+ }
+
+ @Override
+ public Optional<Node> getChild(final PathArgument child) {
+ return Optional.fromNullable(children.get(child));
+ }
+
+ /**
+ * Return the list of current listeners. This collection is guaranteed
+ * to be immutable only while the walker, through which this node is
+ * reachable remains unclosed.
+ *
+ * @return the list of current listeners
+ */
+ public Collection<DataChangeListenerRegistration<?>> getListeners() {
+ return listeners;
+ }
+
+ private Node ensureChild(final PathArgument child) {
+ Node potential = children.get(child);
+ if (potential == null) {
+ potential = new Node(this, child);
+ children.put(child, potential);
+ }
+ return potential;
+ }
+
+ private void addListener(final DataChangeListenerRegistration<?> listener) {
+ listeners.add(listener);
+ LOG.debug("Listener {} registered", listener);
+ }
+
+ private void removeListener(final DataChangeListenerRegistrationImpl<?> listener) {
+ listeners.remove(listener);
+ LOG.debug("Listener {} unregistered", listener);
+
+ // We have been called with the write-lock held, so we can perform some cleanup.
+ removeThisIfUnused();
+ }
+
+ private void removeThisIfUnused() {
+ final Node p = parent.get();
+ if (p != null && listeners.isEmpty() && children.isEmpty()) {
+ p.removeChild(identifier);
+ }
+ }
+
+ private void removeChild(final PathArgument arg) {
+ children.remove(arg);
+ removeThisIfUnused();
+ }
+ }
+
+ private abstract static class DataChangeListenerRegistrationImpl<T extends AsyncDataChangeListener<InstanceIdentifier, NormalizedNode<?, ?>>> extends AbstractListenerRegistration<T> //
+ implements DataChangeListenerRegistration<T> {
+ public DataChangeListenerRegistrationImpl(final T listener) {
+ super(listener);
+ }
+ }
+}
<codeGeneratorClass>
org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
</codeGeneratorClass>
- <outputBaseDir>${project.build.directory}/generated-sources/config</outputBaseDir>
+ <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
<additionalConfiguration>
<namespaceToPackage1>
urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang
</dependencies>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <version>1.8</version>
- <executions>
- <execution>
- <id>add-source</id>
- <phase>generate-sources</phase>
- <goals>
- <goal>add-source</goal>
- </goals>
- <configuration>
- <sources>
- <source>${project.build.directory}/generated-sources/config</source>
- <source>src/main/xtend-gen</source>
- </sources>
- </configuration>
- </execution>
- </executions>
- </plugin>
-
<plugin>
<groupId>org.eclipse.xtend</groupId>
<artifactId>xtend-maven-plugin</artifactId>
</dependency>
</dependencies>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <version>1.8</version>
- <executions>
- <execution>
- <id>add-source</id>
- <phase>generate-sources</phase>
- <goals>
- <goal>add-source</goal>
- </goals>
- <configuration>
- <sources>
- <source>${project.build.directory}/generated-sources/</source>
- </sources>
- </configuration>
- </execution>
- </executions>
- </plugin>
</plugins>
</build>
</project>
<codeGeneratorClass>
org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
</codeGeneratorClass>
- <outputBaseDir>${project.build.directory}/generated-sources/config</outputBaseDir>
+ <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
<additionalConfiguration>
<namespaceToPackage1>
urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang
</instructions>
</configuration>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <version>1.8</version>
- <executions>
- <execution>
- <id>add-source</id>
- <phase>generate-sources</phase>
- <goals>
- <goal>add-source</goal>
- </goals>
- <configuration>
- <sources>
- <source>${project.build.directory}/generated-sources/</source>
- </sources>
- </configuration>
- </execution>
- </executions>
- </plugin>
</plugins>
</build>
</project>
org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
</codeGeneratorClass>
<outputBaseDir>
- target/generated-sources/sal
+ ${salGeneratorPath}
</outputBaseDir>
</generator>
<generator>
<properties>
<sal-binding-api.version>1.1-SNAPSHOT</sal-binding-api.version>
- <jmxGeneratorPath>${project.build.directory}/generated-sources/config</jmxGeneratorPath>
-
</properties>
<build>
</dependencies>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <version>1.8</version>
- <executions>
- <execution>
- <id>add-source</id>
- <phase>generate-sources</phase>
- <goals>
- <goal>add-source</goal>
- </goals>
- <configuration>
- <sources>
- <source>${jmxGeneratorPath}</source>
- </sources>
- </configuration>
- </execution>
- </executions>
- </plugin>
</plugins>
</build>
<properties>
- <jmxGeneratorPath>${project.build.directory}/generated-sources/config</jmxGeneratorPath>
<sal-binding-api.version>1.1-SNAPSHOT</sal-binding-api.version>
</properties>
</dependency>
</dependencies>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <version>1.8</version>
- <executions>
- <execution>
- <id>add-source</id>
- <phase>generate-sources</phase>
- <goals>
- <goal>add-source</goal>
- </goals>
- <configuration>
- <sources>
- <source>${jmxGeneratorPath}</source>
- </sources>
- </configuration>
- </execution>
- </executions>
- </plugin>
</plugins>
</build>
</dependency>
</dependencies>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <version>1.7</version>
- <executions>
- <execution>
- <phase>generate-sources</phase>
- <goals>
- <goal>add-source</goal>
- </goals>
- <configuration>
- <sources>
- <source>target/generated-sources/sal</source>
- </sources>
- </configuration>
- </execution>
- </executions>
- </plugin>
</plugins>
<pluginManagement>
<plugins>
</instructions>
</configuration>
</plugin>
- <plugin>
- <artifactId>maven-clean-plugin</artifactId>
- </plugin>
</plugins>
</build>
</project>
<plugin>
<groupId>org.eclipse.xtend</groupId>
<artifactId>xtend-maven-plugin</artifactId>
- <executions>
- <execution>
- <goals>
- <goal>compile</goal>
- </goals>
- <configuration>
- <outputDirectory>${basedir}/src/main/xtend-gen</outputDirectory>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <artifactId>maven-clean-plugin</artifactId>
- <configuration>
- <filesets>
- <fileset>
- <directory>${basedir}/src/main/xtend-gen</directory>
- <includes>
- <include>**</include>
- </includes>
- </fileset>
- </filesets>
- </configuration>
</plugin>
</plugins>
</build>
<groupId>org.eclipse.xtend</groupId>
<artifactId>xtend-maven-plugin</artifactId>
</plugin>
- <plugin>
- <artifactId>maven-clean-plugin</artifactId>
- </plugin>
</plugins>
</build>
</project>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-maven-plugin</artifactId>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- </plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-maven-plugin</artifactId>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- </plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<osgi.version>5.0.0</osgi.version>
<maven.bundle.version>2.4.0</maven.bundle.version>
<slf4j.version>1.7.2</slf4j.version>
- <salGeneratorPath>${project.build.directory}/generated-sources/sal</salGeneratorPath>
</properties>
<dependencies>
</dependency>
</dependencies>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <version>1.7</version>
- <executions>
- <execution>
- <phase>generate-sources</phase>
- <goals>
- <goal>add-source</goal>
- </goals>
- <configuration>
- <sources>
- <source>${salGeneratorPath}</source>
- </sources>
- </configuration>
- </execution>
- </executions>
- </plugin>
</plugins>
</pluginManagement>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
- <version>1.8</version>
<executions>
<execution>
<id>attach-artifacts</id>
public List<NodeTableStatistics> readAllNodeTable(String containerName, Node node, boolean cached) {
long sid = (Long) node.getID();
List<OFStatistics> ofList = (cached == true) ?
- statsMgr.getOFTableStatistics(sid) : statsMgr.queryStatistics(sid, OFStatisticsType.FLOW, null);
+ statsMgr.getOFTableStatistics(sid) : statsMgr.queryStatistics(sid, OFStatisticsType.TABLE, null);
List<OFStatistics> filteredList = filterTableListPerContainer(containerName, sid, ofList);
+++ /dev/null
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
- <parent>
- <artifactId>yang-prototype</artifactId>
- <groupId>org.opendaylight.controller</groupId>
- <version>0.5-SNAPSHOT</version>
- </parent>
- <scm>
- <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
- <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
- <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
- </scm>
-
- <properties>
- <releaseplugin.version>2.3.2</releaseplugin.version>
- </properties>
-
- <modelVersion>4.0.0</modelVersion>
- <artifactId>concepts-lang</artifactId>
- <packaging>jar</packaging>
- <name>${project.artifactId}</name>
- <description>${project.artifactId}</description>
- <build>
- <pluginManagement>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-release-plugin</artifactId>
- <version>${releaseplugin.version}</version>
- </plugin>
- </plugins>
- </pluginManagement>
- </build>
-</project>
+++ /dev/null
-
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.concepts.lang;
-
-public interface Acceptor<I> {
-
- /**
- *
- * @param input
- * @return true if input is accepted.
- */
- boolean isAcceptable(I input);
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.concepts.lang;
-import java.util.Collection;
-/**
- *
- * @author Tony Tkacik
- *
- * @param <I>
- * @param <P>
- */
-public interface AggregateTransformer<I,P> extends Transformer<I,P> {
-
- Collection<P> transformAll(Collection<? extends I> inputs);
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.concepts.lang;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-
-/**
- * Transformer which aggregates multiple implementations of
- * {@link InputClassBasedTransformer}.
- *
- * The transformation process is driven by {@link Class} of input. The selection
- * of used {@link InputClassBasedTransformer} is done by using the {@link Class}
- * of input as a key to select the transformer.
- *
- * This approach provides quick resolution of transformer, but does not support
- * registering a super type of input to provide transformation support for all
- * subclasses, one must register a new instance of transformer for each valid
- * input class.
- *
- * If you need more flexible selection of transformation consider using
- * {@link CompositeConditionalTransformer} which is slower but most flexible or
- * {@link RuleBasedTransformer} which provides declarative approach for
- * transformation.
- *
- * See {@link #transform(Object)} for more information about tranformation
- * process.
- *
- * @author Tony Tkacik <ttkacik@cisco.com>
- *
- * @param <I>
- * Input super-type
- * @param <P>
- * Product
- */
-public abstract class CompositeClassBasedTransformer<I, P> implements
- InputClassBasedTransformer<I, I, P>,
- AggregateTransformer<I, P> {
-
- private Map<Class<? extends I>, InputClassBasedTransformer<I, ? extends I, P>> transformers = new ConcurrentHashMap<Class<? extends I>, InputClassBasedTransformer<I, ? extends I, P>>();
-
- /**
- * Transforms an input into instance of Product class.
- *
- * The final registered transformer is the one which match following
- * condition:
- *
- * <code>input.getClass() == transformer.getInputClass()</code>
- *
- * This means that transformers are not resolved by class hierarchy, only
- * selected based on final class of the input. If you need more flexible
- * selection of transformation consider using
- * {@link CompositeConditionalTransformer} which is slower but more
- * flexible.
- *
- */
- @Override
- public P transform(I input) {
- @SuppressWarnings("unchecked")
- InputClassBasedTransformer<I, I, P> transformer = (InputClassBasedTransformer<I, I, P>) transformers
- .get(input.getClass());
- if (transformer == null)
- throw new IllegalArgumentException("Transformation of: " + input
- + " is not supported");
- return transformer.transform(input);
- }
-
- /**
- * Registers a new transformer.
- *
- * The transformer is registered for class returned by
- * {@link InputClassBasedTransformer#getInputClass()}. Only one transformer
- * can be registered for particular input class.
- *
- */
- public void addTransformer(
- InputClassBasedTransformer<I, ? extends I, P> transformer)
- throws IllegalStateException {
- if (transformer == null)
- throw new IllegalArgumentException("Transformer should not be null");
- if (transformer.getInputClass() == null)
- throw new IllegalArgumentException(
- "Transformer should specify input class.");
- transformers.put(transformer.getInputClass(), transformer);
- }
-
- /**
- * Removes an registered transformer.
- *
- * Note: Removal is currently unsupported.
- *
- * @param transformer
- * Tranformer to be removed.
- * @throws IllegalArgumentException
- * If the provided transformer is null or is not registered.
- */
- public void removeTransformer(
- InputClassBasedTransformer<I, ? extends I, P> transformer)
- throws IllegalArgumentException {
- throw new UnsupportedOperationException("Not implemented yet");
- }
-
- @Override
- public Collection<P> transformAll(Collection<? extends I> inputs) {
- Collection<P> ret = new ArrayList<P>();
- for (I i : inputs) {
- ret.add(transform(i));
- }
- return ret;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.concepts.lang;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.Set;
-import java.util.TreeSet;
-
-/**
- * Composite transformer which aggregates multiple implementation and selects
- * the one which accepts the input.
- *
- *
- * @author Tony Tkacik
- *
- * @param <I>
- * Input class for transformation
- * @param <P>
- * Product of transformation
- */
-public class CompositeConditionalTransformer<I, P> implements
- SimpleConditionalTransformer<I, P>,
- AggregateTransformer<I,P> {
-
- private final Comparator<TransformerWithPriority<I, P>> comparator = new Comparator<TransformerWithPriority<I, P>>() {
-
- @Override
- public int compare(TransformerWithPriority<I, P> o1,
- TransformerWithPriority<I, P> o2) {
- return Integer.valueOf(o1.priority).compareTo(Integer.valueOf(o2.priority));
- }
-
- };
- private final Set<TransformerWithPriority<I, P>> transformers;
-
- public CompositeConditionalTransformer() {
- // FIXME: Add Ordering
- transformers = new TreeSet<TransformerWithPriority<I, P>>(comparator);
- }
-
- @Override
- public boolean isAcceptable(I input) {
- for (SimpleConditionalTransformer<I, P> trans : transformers) {
- if (trans.isAcceptable(input)) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public P transform(I input) {
- for (SimpleConditionalTransformer<I, P> trans : transformers) {
- if (trans.isAcceptable(input)) {
- return trans.transform(input);
- }
- }
- throw new IllegalStateException(
- "Transformer for provided input is not available.");
- }
-
- public void addTransformer(SimpleConditionalTransformer<I, P> transformer,
- int priority) throws IllegalStateException {
- if (transformer == null) {
- throw new IllegalArgumentException(
- "transformer should not be null.");
- }
- TransformerWithPriority<I, P> withPriority = new TransformerWithPriority<I, P>(
- transformer, priority);
- if (false == transformers.add(withPriority)) {
- throw new IllegalStateException("transformer " + transformer
- + "already registered");
- }
- }
-
- public void removeTransformer(SimpleConditionalTransformer<I, P> transformer)
- throws IllegalArgumentException {
- if (transformer == null) {
- throw new IllegalArgumentException(
- "transformer should not be null.");
- }
- if (false == transformers.remove(transformer)) {
- throw new IllegalStateException("transformer " + transformer
- + "already registered");
- }
- }
-
- @Override
- public Collection<P> transformAll(Collection<? extends I> inputs) {
- Collection<P> ret = new ArrayList<P>();
- for (I i : inputs) {
- ret.add(transform(i));
- }
- return ret;
- }
-
- private static class TransformerWithPriority<I, P> implements
- SimpleConditionalTransformer<I, P> {
- final int priority;
- final SimpleConditionalTransformer<I, P> transformer;
-
- public TransformerWithPriority(
- SimpleConditionalTransformer<I, P> transformer, int priority) {
- this.priority = priority;
- this.transformer = transformer;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result
- + ((transformer == null) ? 0 : transformer.hashCode());
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- TransformerWithPriority<?,?> other = (TransformerWithPriority<?,?>) obj;
- if (transformer == null) {
- if (other.transformer != null)
- return false;
- } else if (!transformer.equals(other.transformer))
- return false;
- return true;
- }
-
- @Override
- public boolean isAcceptable(I input) {
- return transformer.isAcceptable(input);
- }
-
- @Override
- public P transform(I input) {
- return transformer.transform(input);
- }
-
-
-
-
-
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.concepts.lang;
-/**
- * Input class based transformer
- *
- * {@link Transformer} which accepts / transforms only specific classes of
- * input, and is useful if the selection of transformer should be based on the
- * class of the input and there is one-to-one mapping between input class and
- * transformer.
- *
- *
- * @author Tony Tkacik
- *
- * @param <S>
- * Common supertype of input
- * @param <I>
- * Concrete type of input
- * @param <P>
- * Product
- */
-public interface InputClassBasedTransformer<S, I extends S, P> extends
- Transformer<I, P> {
-
- /**
- * Returns an {@link Class} of input which is acceptable for transformation.
- *
- * @return {@link Class} of input which is acceptable for transformation.
- */
- Class<? extends S> getInputClass();
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.concepts.lang;
-import java.util.Set;
-
-/**
- * Transformer with set of acceptance rules
- *
- * The transformer provides a set of {@link Acceptor}s, which could be used to
- * verify if the input will produce result using the transformer.
- *
- * The transormer is able to produce result if ANY of associated
- * {@link Acceptor}s accepted result.
- *
- * @author Tony Tkacik
- *
- * @param <I>
- * Input class for transformation
- * @param <P>
- * Product of transformation
- */
-public interface RuleBasedTransformer<I, P> extends Transformer<I, P> {
-
- /**
- * Set of {@link Acceptor}, which could be used to verify if the input is
- * usable by transformer.
- *
- * The transformer is able to produce result if ANY of associated
- * {@link Acceptor}s accepted result.
- *
- * @return Set of input acceptance rules associated to this transformer.
- */
- Set<Acceptor<I>> getRules();
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.concepts.lang;
-/**
- * Simple condition-based transformer
- *
- * The transformer provides {@link #isAcceptable(Object)} method,
- * which could be used to query transformer if the input will produce
- * result.
- *
- * This interface is simplified version of {@link RuleBasedTransformer} - does not
- * provide decoupling of Acceptance rule from transformer, and should be used only
- * for simple use-cases.
- *
- * @author Tony Tkacik
- *
- * @param <I> Input class for transformation
- * @param <P> Product of transformation
- */
-public interface SimpleConditionalTransformer<I,P> extends Transformer<I, P>, Acceptor<I> {
-
-
- /**
- * Checks if the input is acceptable
- * for processing by the transformer.
- *
- * @return true it the input is acceptable for processing by transformer.
- */
- @Override
- public boolean isAcceptable(I input);
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.concepts.lang;
-/**
- * Factory which produces product based on input object
- *
- * @author Tony Tkacik
- *
- * @param <I> Input
- * @param <P> Product
- */
-public interface Transformer<I,P> {
- /**
- * Transforms input into instance of product.
- *
- * @param input Input which drives transformation
- * @return Instance of product which was created from supplied input.
- */
- P transform(I input);
-}
+++ /dev/null
-<project name="${project.name}">
-
- <skin>
- <groupId>org.apache.maven.skins</groupId>
- <artifactId>maven-fluido-skin</artifactId>
- <version>1.3.0</version>
- </skin>
-
- <body>
- <menu ref="parent"/>
- <menu ref="modules"/>
- <menu ref="reports"/>
- </body>
-
-</project>
-
+++ /dev/null
-SAL
-====================
-
-Project documentation
----------------------
-
-### Description
-
-
-
-### Scope
-
-
-
+++ /dev/null
-/* Javadoc style sheet */
-/*
-Overall document style
-*/
-body {
- background-color:#ffffff;
- color:#353833;
- font-family:Arial, Helvetica, sans-serif;
- font-size:76%;
- margin:0;
-}
-a:link, a:visited {
- text-decoration:none;
- color:#4c6b87;
-}
-a:hover, a:focus {
- text-decoration:none;
- color:#bb7a2a;
-}
-a:active {
- text-decoration:none;
- color:#4c6b87;
-}
-a[name] {
- color:#353833;
-}
-a[name]:hover {
- text-decoration:none;
- color:#353833;
-}
-pre {
- font-size:1.3em;
-}
-h1 {
- font-size:1.8em;
-}
-h2 {
- font-size:1.5em;
-}
-h3 {
- font-size:1.4em;
-}
-h4 {
- font-size:1.3em;
-}
-h5 {
- font-size:1.2em;
-}
-h6 {
- font-size:1.1em;
-}
-ul {
- list-style-type:disc;
-}
-code, tt {
- font-size:1.2em;
-}
-dt code {
- font-size:1.2em;
-}
-table tr td dt code {
- font-size:1.2em;
- vertical-align:top;
-}
-sup {
- font-size:.6em;
-}
-/*
-Document title and Copyright styles
-*/
-.clear {
- clear:both;
- height:0px;
- overflow:hidden;
-}
-.aboutLanguage {
- float:right;
- padding:0px 21px;
- font-size:.8em;
- z-index:200;
- margin-top:-7px;
-}
-.legalCopy {
- margin-left:.5em;
-}
-.bar a, .bar a:link, .bar a:visited, .bar a:active {
- color:#FFFFFF;
- text-decoration:none;
-}
-.bar a:hover, .bar a:focus {
- color:#bb7a2a;
-}
-.tab {
- background-color:#0066FF;
- background-image:url(resources/titlebar.gif);
- background-position:left top;
- background-repeat:no-repeat;
- color:#ffffff;
- padding:8px;
- width:5em;
- font-weight:bold;
-}
-/*
-Navigation bar styles
-*/
-.bar {
- background-image:url(resources/background.gif);
- background-repeat:repeat-x;
- color:#FFFFFF;
- padding:.8em .5em .4em .8em;
- height:auto;/*height:1.8em;*/
- font-size:1em;
- margin:0;
-}
-.topNav {
- background-image:url(resources/background.gif);
- background-repeat:repeat-x;
- color:#FFFFFF;
- float:left;
- padding:0;
- width:100%;
- clear:right;
- height:2.8em;
- padding-top:10px;
- overflow:hidden;
-}
-.bottomNav {
- margin-top:10px;
- background-image:url(resources/background.gif);
- background-repeat:repeat-x;
- color:#FFFFFF;
- float:left;
- padding:0;
- width:100%;
- clear:right;
- height:2.8em;
- padding-top:10px;
- overflow:hidden;
-}
-.subNav {
- background-color:#dee3e9;
- border-bottom:1px solid #9eadc0;
- float:left;
- width:100%;
- overflow:hidden;
-}
-.subNav div {
- clear:left;
- float:left;
- padding:0 0 5px 6px;
-}
-ul.navList, ul.subNavList {
- float:left;
- margin:0 25px 0 0;
- padding:0;
-}
-ul.navList li{
- list-style:none;
- float:left;
- padding:3px 6px;
-}
-ul.subNavList li{
- list-style:none;
- float:left;
- font-size:90%;
-}
-.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited {
- color:#FFFFFF;
- text-decoration:none;
-}
-.topNav a:hover, .bottomNav a:hover {
- text-decoration:none;
- color:#bb7a2a;
-}
-.navBarCell1Rev {
- background-image:url(resources/tab.gif);
- background-color:#a88834;
- color:#FFFFFF;
- margin: auto 5px;
- border:1px solid #c9aa44;
-}
-/*
-Page header and footer styles
-*/
-.header, .footer {
- clear:both;
- margin:0 20px;
- padding:5px 0 0 0;
-}
-.indexHeader {
- margin:10px;
- position:relative;
-}
-.indexHeader span{
- margin-right:15px;
-}
-.indexHeader h1 {
- font-size:1.3em;
-}
-.title {
- color:#2c4557;
- margin:10px 0;
-}
-.subTitle {
- margin:5px 0 0 0;
-}
-.header ul {
- margin:0 0 25px 0;
- padding:0;
-}
-.footer ul {
- margin:20px 0 5px 0;
-}
-.header ul li, .footer ul li {
- list-style:none;
- font-size:1.2em;
-}
-/*
-Heading styles
-*/
-div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 {
- background-color:#dee3e9;
- border-top:1px solid #9eadc0;
- border-bottom:1px solid #9eadc0;
- margin:0 0 6px -8px;
- padding:2px 5px;
-}
-ul.blockList ul.blockList ul.blockList li.blockList h3 {
- background-color:#dee3e9;
- border-top:1px solid #9eadc0;
- border-bottom:1px solid #9eadc0;
- margin:0 0 6px -8px;
- padding:2px 5px;
-}
-ul.blockList ul.blockList li.blockList h3 {
- padding:0;
- margin:15px 0;
-}
-ul.blockList li.blockList h2 {
- padding:0px 0 20px 0;
-}
-/*
-Page layout container styles
-*/
-.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer {
- clear:both;
- padding:10px 20px;
- position:relative;
-}
-.indexContainer {
- margin:10px;
- position:relative;
- font-size:1.0em;
-}
-.indexContainer h2 {
- font-size:1.1em;
- padding:0 0 3px 0;
-}
-.indexContainer ul {
- margin:0;
- padding:0;
-}
-.indexContainer ul li {
- list-style:none;
-}
-.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt {
- font-size:1.1em;
- font-weight:bold;
- margin:10px 0 0 0;
- color:#4E4E4E;
-}
-.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd {
- margin:10px 0 10px 20px;
-}
-.serializedFormContainer dl.nameValue dt {
- margin-left:1px;
- font-size:1.1em;
- display:inline;
- font-weight:bold;
-}
-.serializedFormContainer dl.nameValue dd {
- margin:0 0 0 1px;
- font-size:1.1em;
- display:inline;
-}
-/*
-List styles
-*/
-ul.horizontal li {
- display:inline;
- font-size:0.9em;
-}
-ul.inheritance {
- margin:0;
- padding:0;
-}
-ul.inheritance li {
- display:inline;
- list-style:none;
-}
-ul.inheritance li ul.inheritance {
- margin-left:15px;
- padding-left:15px;
- padding-top:1px;
-}
-ul.blockList, ul.blockListLast {
- margin:10px 0 10px 0;
- padding:0;
-}
-ul.blockList li.blockList, ul.blockListLast li.blockList {
- list-style:none;
- margin-bottom:25px;
-}
-ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList {
- padding:0px 20px 5px 10px;
- border:1px solid #9eadc0;
- background-color:#f9f9f9;
-}
-ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList {
- padding:0 0 5px 8px;
- background-color:#ffffff;
- border:1px solid #9eadc0;
- border-top:none;
-}
-ul.blockList ul.blockList ul.blockList ul.blockList li.blockList {
- margin-left:0;
- padding-left:0;
- padding-bottom:15px;
- border:none;
- border-bottom:1px solid #9eadc0;
-}
-ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast {
- list-style:none;
- border-bottom:none;
- padding-bottom:0;
-}
-table tr td dl, table tr td dl dt, table tr td dl dd {
- margin-top:0;
- margin-bottom:1px;
-}
-/*
-Table styles
-*/
-.contentContainer table, .classUseContainer table, .constantValuesContainer table {
- border-bottom:1px solid #9eadc0;
- width:100%;
-}
-.contentContainer ul li table, .classUseContainer ul li table, .constantValuesContainer ul li table {
- width:100%;
-}
-.contentContainer .description table, .contentContainer .details table {
- border-bottom:none;
-}
-.contentContainer ul li table th.colOne, .contentContainer ul li table th.colFirst, .contentContainer ul li table th.colLast, .classUseContainer ul li table th, .constantValuesContainer ul li table th, .contentContainer ul li table td.colOne, .contentContainer ul li table td.colFirst, .contentContainer ul li table td.colLast, .classUseContainer ul li table td, .constantValuesContainer ul li table td{
- vertical-align:top;
- padding-right:20px;
-}
-.contentContainer ul li table th.colLast, .classUseContainer ul li table th.colLast,.constantValuesContainer ul li table th.colLast,
-.contentContainer ul li table td.colLast, .classUseContainer ul li table td.colLast,.constantValuesContainer ul li table td.colLast,
-.contentContainer ul li table th.colOne, .classUseContainer ul li table th.colOne,
-.contentContainer ul li table td.colOne, .classUseContainer ul li table td.colOne {
- padding-right:3px;
-}
-.overviewSummary caption, .packageSummary caption, .contentContainer ul.blockList li.blockList caption, .summary caption, .classUseContainer caption, .constantValuesContainer caption {
- position:relative;
- text-align:left;
- background-repeat:no-repeat;
- color:#FFFFFF;
- font-weight:bold;
- clear:none;
- overflow:hidden;
- padding:0px;
- margin:0px;
- white-space:pre;
-}
-caption a:link, caption a:hover, caption a:active, caption a:visited {
- color:#FFFFFF;
-}
-.overviewSummary caption span, .packageSummary caption span, .contentContainer ul.blockList li.blockList caption span, .summary caption span, .classUseContainer caption span, .constantValuesContainer caption span {
- white-space:nowrap;
- padding-top:8px;
- padding-left:8px;
- display:block;
- float:left;
- background-image:url(resources/titlebar.gif);
- height:18px;
-}
-.contentContainer ul.blockList li.blockList caption span.activeTableTab span {
- white-space:nowrap;
- padding-top:8px;
- padding-left:8px;
- display:block;
- float:left;
- background-image:url(resources/activetitlebar.gif);
- height:18px;
-}
-.contentContainer ul.blockList li.blockList caption span.tableTab span {
- white-space:nowrap;
- padding-top:8px;
- padding-left:8px;
- display:block;
- float:left;
- background-image:url(resources/titlebar.gif);
- height:18px;
-}
-.contentContainer ul.blockList li.blockList caption span.tableTab, .contentContainer ul.blockList li.blockList caption span.activeTableTab {
- padding-top:0px;
- padding-left:0px;
- background-image:none;
- float:none;
- display:inline;
-}
-.overviewSummary .tabEnd, .packageSummary .tabEnd, .contentContainer ul.blockList li.blockList .tabEnd, .summary .tabEnd, .classUseContainer .tabEnd, .constantValuesContainer .tabEnd {
- width:10px;
- background-image:url(resources/titlebar_end.gif);
- background-repeat:no-repeat;
- background-position:top right;
- position:relative;
- float:left;
-}
-.contentContainer ul.blockList li.blockList .activeTableTab .tabEnd {
- width:10px;
- margin-right:5px;
- background-image:url(resources/activetitlebar_end.gif);
- background-repeat:no-repeat;
- background-position:top right;
- position:relative;
- float:left;
-}
-.contentContainer ul.blockList li.blockList .tableTab .tabEnd {
- width:10px;
- margin-right:5px;
- background-image:url(resources/titlebar_end.gif);
- background-repeat:no-repeat;
- background-position:top right;
- position:relative;
- float:left;
-}
-ul.blockList ul.blockList li.blockList table {
- margin:0 0 12px 0px;
- width:100%;
-}
-.tableSubHeadingColor {
- background-color: #EEEEFF;
-}
-.altColor {
- background-color:#eeeeef;
-}
-.rowColor {
- background-color:#ffffff;
-}
-.overviewSummary td, .packageSummary td, .contentContainer ul.blockList li.blockList td, .summary td, .classUseContainer td, .constantValuesContainer td {
- text-align:left;
- padding:3px 3px 3px 7px;
-}
-th.colFirst, th.colLast, th.colOne, .constantValuesContainer th {
- background:#dee3e9;
- border-top:1px solid #9eadc0;
- border-bottom:1px solid #9eadc0;
- text-align:left;
- padding:3px 3px 3px 7px;
-}
-td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover {
- font-weight:bold;
-}
-td.colFirst, th.colFirst {
- border-left:1px solid #9eadc0;
- white-space:nowrap;
-}
-td.colLast, th.colLast {
- border-right:1px solid #9eadc0;
-}
-td.colOne, th.colOne {
- border-right:1px solid #9eadc0;
- border-left:1px solid #9eadc0;
-}
-table.overviewSummary {
- padding:0px;
- margin-left:0px;
-}
-table.overviewSummary td.colFirst, table.overviewSummary th.colFirst,
-table.overviewSummary td.colOne, table.overviewSummary th.colOne {
- width:25%;
- vertical-align:middle;
-}
-table.packageSummary td.colFirst, table.overviewSummary th.colFirst {
- width:25%;
- vertical-align:middle;
-}
-/*
-Content styles
-*/
-.description pre {
- margin-top:0;
-}
-.deprecatedContent {
- margin:0;
- padding:10px 0;
-}
-.docSummary {
- padding:0;
-}
-/*
-Formatting effect styles
-*/
-.sourceLineNo {
- color:green;
- padding:0 30px 0 0;
-}
-h1.hidden {
- visibility:hidden;
- overflow:hidden;
- font-size:.9em;
-}
-.block {
- display:block;
- margin:3px 0 0 0;
-}
-.strong {
- font-weight:bold;
-}
-
+++ /dev/null
-<project name="${project.name}">
-
- <skin>
- <groupId>org.apache.maven.skins</groupId>
- <artifactId>maven-fluido-skin</artifactId>
- <version>1.3.0</version>
- </skin>
-
- <body>
- <menu ref="parent"/>
- <menu ref="modules"/>
- <menu ref="reports"/>
- <menu name="Overview">
- <item name="Readme" href="readme.html" />
- </menu>
- </body>
-
-</project>