kmcpeake
Committed by Gerrit Code Review

CHANGE 1:

Patch to show API for Alarms in Fault Management.
AlarmsWebResource.java & Alarm.java show what the external REST API for alarms would look like.
See more info at https://wiki.onosproject.org/display/ONOS/Fault+Management
Everything else is very early and work-in-progress/mostly just stubbed out, and not ready for review but all advice welcome.

CHANGE 2:
[ONOS-3203] Update re. comments on FM API draft.
Comments were from Thomas Vachuska regarding https://gerrit.onosproject.org/#/c/6180/
Change-Id: If8d330d1b18b503e89849587e2d4388bf67becc0
Showing 39 changed files with 2731 additions and 0 deletions
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2015 Open Networking Laboratory
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<app name="org.onosproject.faultmanagement" origin="BTI Systems" version="${project.version}"
featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features"
features="${project.artifactId}">
<description>${project.description}</description>
<artifact>mvn:${project.groupId}/onos-app-fm-mgr/${project.version}</artifact>
<artifact>mvn:${project.groupId}/onos-app-fm-web/${project.version}</artifact>
</app>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
~ Copyright 2015 Open Networking Laboratory
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" name="${project.artifactId}-${project.version}">
<feature name="${project.artifactId}" version="${project.version}"
description="${project.description}">
<feature>onos-api</feature>
<feature>onos-drivers</feature>
<bundle>mvn:${project.groupId}/onos-app-fm-mgr/${project.version}</bundle>
<bundle>mvn:${project.groupId}/onos-app-fm-web/${project.version}</bundle>
</feature>
</features>
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2015 Open Networking Laboratory
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.onosproject</groupId>
<artifactId>onos-app-fm</artifactId>
<version>1.4.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>onos-app-fm-onosfw</artifactId>
<packaging>pom</packaging>
<description>ONOS framework applications</description>
<dependencies>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-app-fm-web</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-app-fm-mgr</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>
<?xml version="1.0"?>
<!--
~ Copyright 2015 Open Networking Laboratory
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.onosproject</groupId>
<artifactId>onos-app-fm</artifactId>
<version>1.4.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>onos-app-fm-mgr</artifactId>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-incubator-api</artifactId>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-core-serializers</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.compendium</artifactId>
<version>5.0.0</version>
<type>jar</type>
</dependency>
</dependencies>
</project>
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.faultmanagement.impl;
import static com.google.common.base.Strings.isNullOrEmpty;
import java.util.Dictionary;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Modified;
import org.apache.felix.scr.annotations.Property;
import static org.onlab.util.Tools.nullIsNotFound;
import org.onosproject.incubator.net.faultmanagement.alarm.Alarm;
import org.onosproject.incubator.net.faultmanagement.alarm.AlarmEntityId;
import org.onosproject.incubator.net.faultmanagement.alarm.AlarmEvent;
import org.onosproject.incubator.net.faultmanagement.alarm.AlarmId;
import org.onosproject.incubator.net.faultmanagement.alarm.AlarmListener;
import org.onosproject.incubator.net.faultmanagement.alarm.AlarmService;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DeviceId;
import org.slf4j.Logger;
import static org.slf4j.LoggerFactory.getLogger;
import org.apache.felix.scr.annotations.Service;
import static org.onlab.util.Tools.get;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.IdGenerator;
import org.onosproject.core.CoreService;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onlab.util.ItemNotFoundException;
import org.onosproject.incubator.net.faultmanagement.alarm.DefaultAlarm;
import org.osgi.service.component.ComponentContext;
/**
* Implementation of the Alarm service.
*/
@Component(immediate = true)
@Service
public class AlarmsManager implements AlarmService {
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
private final Logger log = getLogger(getClass());
private ApplicationId appId;
private IdGenerator idGenerator;
@Property(name = "fmDevices", value = "127.0.0.1", label = "Instance-specific configurations")
private String devConfigs;
private final Map<AlarmId, Alarm> alarms = new ConcurrentHashMap<>();
private final AtomicLong alarmIdGenerator = new AtomicLong(0);
@Override
public Alarm update(final Alarm replacement) {
final Alarm found = alarms.get(replacement.id());
if (found == null) {
throw new ItemNotFoundException("Alarm with id " + replacement.id() + " found");
}
final Alarm updated = new DefaultAlarm.Builder(found).
withAcknowledged(replacement.acknowledged()).
withAssignedUser(replacement.assignedUser()).build();
alarms.put(replacement.id(), updated);
return updated;
}
@Override
public int getActiveAlarmCount(final DeviceId deviceId) {
//TODO
throw new UnsupportedOperationException(NOT_SUPPORTED_YET);
}
private static final String NOT_SUPPORTED_YET = "Not supported yet.";
@Override
public Alarm getAlarm(final AlarmId alarmId) {
return nullIsNotFound(
alarms.get(alarmId),
"Alarm is not found");
}
@Override
public Set<Alarm> getAlarms() {
//TODO
throw new UnsupportedOperationException(NOT_SUPPORTED_YET);
}
@Override
public Set<Alarm> getActiveAlarms() {
// Enpty set if no values
return alarms.isEmpty() ? new HashSet<>() : new HashSet<>(alarms.values());
}
private static DefaultAlarm generateFake(final DeviceId deviceId, final AlarmId alarmId) {
return new DefaultAlarm.Builder(
alarmId, deviceId, "NE is not reachable", Alarm.SeverityLevel.MAJOR, System.currentTimeMillis()).
withTimeUpdated(System.currentTimeMillis()).
withServiceAffecting(true)
.withAcknowledged(true).
withManuallyClearable(true)
.withAssignedUser("user1").build();
}
@Override
public Set<Alarm> getAlarms(final Alarm.SeverityLevel severity) {
//TODO
throw new UnsupportedOperationException(NOT_SUPPORTED_YET);
}
@Override
public Set<Alarm> getAlarms(final DeviceId deviceId) {
//TODO
throw new UnsupportedOperationException(NOT_SUPPORTED_YET);
}
@Override
public Set<Alarm> getAlarms(final DeviceId deviceId, final AlarmEntityId source) {
//TODO
throw new UnsupportedOperationException(NOT_SUPPORTED_YET);
}
@Override
public Set<Alarm> getAlarmsForLink(final ConnectPoint src, final ConnectPoint dst) {
//TODO
throw new UnsupportedOperationException(NOT_SUPPORTED_YET);
}
@Override
public Set<Alarm> getAlarmsForFlow(final DeviceId deviceId, final long flowId) {
//TODO
throw new UnsupportedOperationException(NOT_SUPPORTED_YET);
}
private void discoverAlarmsForDevice(final DeviceId deviceId) {
final AlarmId alarmId = new AlarmId(alarmIdGenerator.incrementAndGet());
// TODO In a new thread invoke SNMP Provider with DeviceId and device type and when done update our of alarms
//
alarms.put(alarmId, generateFake(deviceId, alarmId));
}
private class InternalAlarmListener implements AlarmListener {
@Override
public void event(final AlarmEvent event) {
// TODO
throw new UnsupportedOperationException(NOT_SUPPORTED_YET);
}
}
@Activate
public void activate(final ComponentContext context) {
log.info("Activate ...");
appId = coreService.registerApplication("org.onos.faultmanagement.alarms");
idGenerator = coreService.getIdGenerator("alarm-ids");
log.info("Started with appId={} idGenerator={}", appId, idGenerator);
final boolean result = modified(context);
log.info("modified result = {}", result);
}
@Deactivate
public void deactivate(final ComponentContext context) {
log.info("Deactivate ...");
// cfgService.unregisterProperties(getClass(), false);
log.info("Stopped");
}
@Modified
public boolean modified(final ComponentContext context) {
log.info("context={}", context);
if (context == null) {
log.info("No configuration file");
return false;
}
final Dictionary<?, ?> properties = context.getProperties();
final String ipaddresses = get(properties, "fmDevices");
log.info("Settings: devConfigs={}", ipaddresses);
if (!isNullOrEmpty(ipaddresses)) {
discover(ipaddresses);
}
return true;
}
private void discover(final String ipaddresses) {
for (String deviceEntry : ipaddresses.split(",")) {
final DeviceId deviceId = DeviceId.deviceId(deviceEntry);
if (deviceId != null) {
log.info("Device {} needs to have its alarms refreshed!", deviceId);
discoverAlarmsForDevice(deviceId);
}
}
}
}
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Fault Management application implementation.
*/
package org.onosproject.faultmanagement.impl;
<?xml version="1.0"?>
<!--
~ Copyright 2015 Open Networking Laboratory
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.onosproject</groupId>
<artifactId>onos-app-fm</artifactId>
<version>1.4.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>onos-app-fm-web</artifactId>
<packaging>bundle</packaging>
<properties>
<web.context>/onos/v1/fm</web.context>
<api.version>1.0.0</api.version>
<api.title>ONOS Fault Management Application REST API</api.title>
<api.description>
APIs for interacting with the Fault Management application.
</api.description>
<api.package>org.onos.faultmanagement.web</api.package>
</properties>
<dependencies>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-incubator-api</artifactId>
<version>${project.version}</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onlab-osgi</artifactId>
<version>${project.version}</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.19</version>
<scope>test</scope>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-core-common</artifactId>
<version>${project.version}</version>
<scope>test</scope>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-rest</artifactId>
<version>${project.version}</version>
<scope>test</scope>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-rest</artifactId>
<version>${project.version}</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.sun.jersey.jersey-test-framework</groupId>
<artifactId>jersey-test-framework-core</artifactId>
<version>1.19</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<_wab>src/main/webapp/</_wab>
<Include-Resource>
WEB-INF/classes/apidoc/swagger.json=target/swagger.json,
{maven-resources}
</Include-Resource>
<Bundle-SymbolicName>
${project.groupId}.${project.artifactId}
</Bundle-SymbolicName>
<Import-Package>
org.slf4j,
org.osgi.framework,
javax.ws.rs,
javax.ws.rs.core,
com.sun.jersey.api.core,
com.sun.jersey.spi.container.servlet,
com.sun.jersey.server.impl.container.servlet,
com.fasterxml.jackson.databind,
com.fasterxml.jackson.databind.node,
com.fasterxml.jackson.core,
org.apache.karaf.shell.commands,
org.apache.commons.lang.math.*,
com.google.common.*,
org.onlab.packet.*,
org.onlab.rest.*,
org.onosproject.*,
org.onlab.util.*,
org.jboss.netty.util.*
</Import-Package>
<Web-ContextPath>${web.context}</Web-ContextPath>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.faultmanagement.web;
import com.fasterxml.jackson.databind.JsonNode;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import com.fasterxml.jackson.databind.node.ObjectNode;
import static com.google.common.base.Preconditions.checkNotNull;
import org.onosproject.net.DeviceId;
import org.onosproject.incubator.net.faultmanagement.alarm.Alarm;
import org.onosproject.incubator.net.faultmanagement.alarm.AlarmEntityId;
import org.onosproject.incubator.net.faultmanagement.alarm.AlarmId;
import org.onosproject.incubator.net.faultmanagement.alarm.DefaultAlarm;
import org.slf4j.Logger;
import static org.slf4j.LoggerFactory.getLogger;
/**
* Implementation of encoder for Alarm codec.
*/
public final class AlarmCodec extends JsonCodec<Alarm> {
private final Logger log = getLogger(getClass());
@Override
public ObjectNode encode(final Alarm alarm, final CodecContext context) {
checkNotNull(alarm, "Alarm cannot be null");
return context.mapper().createObjectNode()
.put("id", alarm.id().fingerprint())
.put("deviceId", alarm.deviceId().toString())
.put("description", alarm.description())
.put("source",
alarm.source() == null ? null
: alarm.source().toString())
.put("timeRaised", alarm.timeRaised())
.put("timeUpdated", alarm.timeUpdated())
.put("timeCleared", alarm.timeCleared())
.put("severity", alarm.severity().toString())
.put("serviceAffecting", alarm.serviceAffecting())
.put("acknowledged", alarm.acknowledged())
.put("manuallyClearable", alarm.manuallyClearable())
.put("assignedUser", alarm.assignedUser());
}
@Override
public Alarm decode(final ObjectNode json, final CodecContext context) {
if (json == null || !json.isObject()) {
return null;
}
log.debug("id={}, full json={} ", json.get("id"), json);
final Long id = json.get("id").asLong();
final DeviceId deviceId = DeviceId.deviceId(json.get("deviceId").asText());
final String description = json.get("description").asText();
final Long timeRaised = json.get("timeRaised").asLong();
final Long timeUpdated = json.get("timeUpdated").asLong();
final JsonNode jsonTimeCleared = json.get("timeCleared");
final Long timeCleared = jsonTimeCleared == null || jsonTimeCleared.isNull() ? null : jsonTimeCleared.asLong();
final Alarm.SeverityLevel severity
= Alarm.SeverityLevel.valueOf(json.get("severity").asText().toUpperCase());
final Boolean serviceAffecting = json.get("serviceAffecting").asBoolean();
final Boolean acknowledged = json.get("acknowledged").asBoolean();
final Boolean manuallyClearable = json.get("manuallyClearable").asBoolean();
final JsonNode jsonAssignedUser = json.get("assignedUser");
final String assignedUser
= jsonAssignedUser == null || jsonAssignedUser.isNull() ? null : jsonAssignedUser.asText();
return new DefaultAlarm.Builder(
AlarmId.valueOf(id), deviceId, description, severity, timeRaised).forSource(AlarmEntityId.NONE).
withTimeUpdated(timeUpdated).
withTimeCleared(timeCleared).
withServiceAffecting(serviceAffecting).
withAcknowledged(acknowledged).
withManuallyClearable(manuallyClearable).
withAssignedUser(assignedUser).
build();
}
}
/*
* Copyright 2014-2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.faultmanagement.web;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.io.IOException;
import java.io.InputStream;
import org.onosproject.rest.AbstractWebResource;
import javax.ws.rs.core.Response;
import org.onosproject.incubator.net.faultmanagement.alarm.Alarm;
import org.onosproject.incubator.net.faultmanagement.alarm.AlarmId;
import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import org.onosproject.codec.CodecService;
import org.onosproject.incubator.net.faultmanagement.alarm.AlarmService;
import org.slf4j.Logger;
import static org.slf4j.LoggerFactory.getLogger;
/**
* Alarms on devices or ONOS.
*/
@Path("alarms")
public class AlarmsWebResource extends AbstractWebResource {
public static final String ALARM_NOT_FOUND = "Alarm is not found";
private final Logger log = getLogger(getClass());
public AlarmsWebResource() {
get(CodecService.class).registerCodec(Alarm.class, new AlarmCodec());
}
/**
* Get all alarms. Returns a list of all alarms across all devices.
*
* @param includeCleared include recently cleared alarms in response
* @return JSON encoded set of alarms
*/
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getAlarms(@DefaultValue("false") @QueryParam("includeCleared") final boolean includeCleared
) {
log.info("Requesting all alarms, includeCleared={}", includeCleared);
final AlarmService service = get(AlarmService.class);
final Iterable<Alarm> alarms = includeCleared
? service.getAlarms()
: service.getActiveAlarms();
final ObjectNode result = new ObjectMapper().createObjectNode();
result.set("alarms",
codec(Alarm.class).
encode(alarms, this));
return ok(result.toString()).build();
}
/**
* Get specified alarm. Returns details of the specified alarm.
*
* @param id ONOS allocated identifier
* @return JSON encoded alarm
*/
@GET
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response getAlarm(@PathParam("id") final String id) {
log.info("HTTP GET alarm for id={}", id);
final AlarmId alarmId = toAlarmId(id);
final Alarm alarm = get(AlarmService.class).getAlarm(alarmId);
final ObjectNode result = mapper().createObjectNode();
result.set("alarm", codec(Alarm.class).encode(alarm, this));
return ok(result.toString()).build();
}
/**
* Update book-keeping fields on the alarm. Returns an up-to-date version of the alarm. Some of its fields may have
* been updated since the REST client last retrieved the alarm being updated.
*
* @param alarmIdPath
* @param stream input JSON
* @return updated JSON encoded alarm
*/
@PUT
@Path("{alarm_id}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response update(@PathParam("alarm_id") final String alarmIdPath, final InputStream stream) {
log.info("PUT NEW ALARM at /{}", alarmIdPath);
try {
final ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
log.info("jsonTree={}", jsonTree);
final Alarm alarm = codec(Alarm.class).decode(jsonTree, this);
final AlarmService service = get(AlarmService.class);
if (Long.parseLong(alarmIdPath) != alarm.id().fingerprint()) {
throw new IllegalArgumentException("id in path is " + Long.parseLong(alarmIdPath)
+ " but payload uses id=" + alarm.id().fingerprint());
}
final Alarm updated = service.update(alarm);
final ObjectNode encoded = new AlarmCodec().encode(updated, this);
return ok(encoded.toString()).build();
} catch (IOException ioe) {
throw new IllegalArgumentException(ioe);
}
}
private static AlarmId toAlarmId(final String id) {
try {
return AlarmId.valueOf(Long.parseLong(id));
} catch (NumberFormatException ex) {
throw new IllegalArgumentException("Alarm id should be numeric", ex);
}
}
}
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Fault management web support.
*/
package org.onosproject.faultmanagement.web;
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2015 Open Networking Laboratory
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="ONOS" version="2.5">
<display-name>FM2 REST API v1.0</display-name>
<servlet>
<servlet-name>JAX-RS Service</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.resourceConfigClass</param-name>
<param-value>com.sun.jersey.api.core.ClassNamesResourceConfig</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.property.classnames</param-name>
<param-value>
org.onosproject.faultmanagement.web.AlarmsWebResource</param-value>
</init-param>
<load-on-startup>10</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>JAX-RS Service</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.faultmanagement.web;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.onosproject.incubator.net.faultmanagement.alarm.Alarm;
/**
* Mock codec context for use in codec unit tests.
*/
public class AlarmCodecContext implements CodecContext {
private final ObjectMapper mapper = new ObjectMapper();
private final Map<Class<?>, JsonCodec> codecs = new ConcurrentHashMap<>();
/**
* Constructs a new mock codec context.
*/
public AlarmCodecContext() {
codecs.clear();
registerCodec(Alarm.class, new AlarmCodec());
}
@Override
public ObjectMapper mapper() {
return mapper;
}
@SuppressWarnings("unchecked")
@Override
public <T> T getService(Class<T> serviceClass) {
// TODO
return null;
}
/**
* Registers the specified JSON codec for the given entity class.
*
* @param entityClass entity class
* @param codec JSON codec
* @param <T> entity type
*/
public <T> void registerCodec(Class<T> entityClass, JsonCodec<T> codec) {
codecs.putIfAbsent(entityClass, codec);
}
@SuppressWarnings("unchecked")
@Override
public <T> JsonCodec<T> codec(Class<T> entityClass) {
return codecs.get(entityClass);
}
}
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.faultmanagement.web;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.io.IOException;
import java.io.InputStream;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import org.junit.Test;
import org.onosproject.codec.JsonCodec;
import static org.onosproject.faultmanagement.web.AlarmJsonMatcher.matchesAlarm;
import org.onosproject.net.DeviceId;
import org.onosproject.incubator.net.faultmanagement.alarm.Alarm;
import org.onosproject.incubator.net.faultmanagement.alarm.AlarmEntityId;
import org.onosproject.incubator.net.faultmanagement.alarm.AlarmId;
import org.onosproject.incubator.net.faultmanagement.alarm.DefaultAlarm;
public class AlarmCodecTest {
private final AlarmCodecContext context = new AlarmCodecContext();
// Use this to check handling for miminal Alarm
private final Alarm alarmMinimumFields = new DefaultAlarm.Builder(
new AlarmId(44),
DeviceId.deviceId("of:2222000000000000"),
"NE unreachable",
Alarm.SeverityLevel.CLEARED,
1).
build();
// Use this to check handling for fully populated Alarm
private final Alarm alarmWithSource = new DefaultAlarm.Builder(
new AlarmId(44),
DeviceId.deviceId("of:2222000000000000"),
"NE unreachable",
Alarm.SeverityLevel.CLEARED, 1).
forSource(AlarmEntityId.alarmEntityId("port:1/2/3/4")).
withTimeUpdated(2).
withTimeCleared(3L).
withServiceAffecting(true).
withAcknowledged(true).
withManuallyClearable(true).
withAssignedUser("the assigned user").build();
@Test
public void alarmCodecTestWithOptionalFieldMissing() {
//context.registerService(AlarmService.class, new AlarmServiceAdapter());
final JsonCodec<Alarm> codec = context.codec(Alarm.class);
assertThat(codec, is(notNullValue()));
final ObjectNode alarmJson = codec.encode(alarmMinimumFields, context);
assertThat(alarmJson, notNullValue());
assertThat(alarmJson, matchesAlarm(alarmMinimumFields));
}
@Test
public void alarmCodecTestWithOptionalField() {
final JsonCodec<Alarm> codec = context.codec(Alarm.class);
assertThat(codec, is(notNullValue()));
final ObjectNode alarmJson = codec.encode(alarmWithSource, context);
assertThat(alarmJson, notNullValue());
assertThat(alarmJson, matchesAlarm(alarmWithSource));
}
@Test
public void verifyMinimalAlarmIsEncoded() throws Exception {
final JsonCodec<Alarm> alarmCodec = context.codec(Alarm.class);
final Alarm alarm = getDecodedAlarm(alarmCodec, "alarm-minimal.json");
assertCommon(alarm);
assertThat(alarm.timeCleared(), nullValue());
assertThat(alarm.assignedUser(), nullValue());
}
@Test
public void verifyFullyLoadedAlarmIsEncoded() throws Exception {
final JsonCodec<Alarm> alarmCodec = context.codec(Alarm.class);
final Alarm alarm = getDecodedAlarm(alarmCodec, "alarm-full.json");
assertCommon(alarm);
assertThat(alarm.timeCleared(), is(2222L));
assertThat(alarm.assignedUser(), is("foo"));
}
private void assertCommon(final Alarm alarm) {
assertThat(alarm.id(), is(new AlarmId(10L)));
assertThat(alarm.description(), is("NE is not reachable"));
assertThat(alarm.source(), is(AlarmEntityId.NONE));
assertThat(alarm.timeRaised(), is(999L));
assertThat(alarm.timeUpdated(), is(1111L));
assertThat(alarm.severity(), is(Alarm.SeverityLevel.MAJOR));
assertThat(alarm.serviceAffecting(), is(true));
assertThat(alarm.acknowledged(), is(false));
assertThat(alarm.manuallyClearable(), is(true));
}
/**
* Reads in a rule from the given resource and decodes it.
*
* @param resourceName resource to use to read the JSON for the rule
* @return decoded flow rule
* @throws IOException if processing the resource failsdecode
*/
private Alarm getDecodedAlarm(final JsonCodec<Alarm> codec, final String resourceName) throws IOException {
final InputStream jsonStream = AlarmCodecTest.class
.getResourceAsStream(resourceName);
final JsonNode json = context.mapper().readTree(jsonStream);
assertThat(json, notNullValue());
final Alarm result = codec.decode((ObjectNode) json, context);
assertThat(result, notNullValue());
return result;
}
}
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.faultmanagement.web;
import org.hamcrest.Description;
import org.hamcrest.TypeSafeDiagnosingMatcher;
import org.onosproject.incubator.net.faultmanagement.alarm.Alarm;
import com.fasterxml.jackson.databind.JsonNode;
/**
* Hamcrest matcher for alarms.
*/
public final class AlarmJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNode> {
private final Alarm alarm;
private AlarmJsonMatcher(final Alarm alarm) {
this.alarm = alarm;
}
@Override
public boolean matchesSafely(final JsonNode jsonAlarm, final Description description) {
final String jsonAlarmId = jsonAlarm.get("id").asText();
final String alarmId = Long.toString(alarm.id().fingerprint());
if (!jsonAlarmId.equals(alarmId)) {
description.appendText("alarm id was " + jsonAlarmId);
return false;
}
final String jsonDeviceId = jsonAlarm.get("deviceId").asText();
final String alarmDeviceId = alarm.deviceId().toString();
if (!jsonDeviceId.equals(alarmDeviceId)) {
description.appendText("DeviceId was " + jsonDeviceId);
return false;
}
final String jsonDescription = jsonAlarm.get("description").asText();
final String alarmDesc = alarm.description();
if (!jsonDescription.equals(alarmDesc)) {
description.appendText("description was " + jsonDescription);
return false;
}
final long jsonTimeRaised = jsonAlarm.get("timeRaised").asLong();
final long timeRaised = alarm.timeRaised();
if (timeRaised != jsonTimeRaised) {
description.appendText("timeRaised was " + jsonTimeRaised);
return false;
}
final long jsonTimeUpdated = jsonAlarm.get("timeUpdated").asLong();
final long timeUpdated = alarm.timeUpdated();
if (timeUpdated != jsonTimeUpdated) {
description.appendText("timeUpdated was " + jsonTimeUpdated);
return false;
}
final JsonNode jsonTimeClearedNode = jsonAlarm.get("timeCleared");
if (alarm.timeCleared() != null) {
final Long jsonTimeCleared = jsonTimeClearedNode.longValue();
final Long timeCleared = alarm.timeCleared();
if (!timeCleared.equals(jsonTimeCleared)) {
description.appendText("Time Cleared was " + jsonTimeCleared);
return false;
}
} else {
// No clear time not specified, JSON representation must be empty
if (!jsonTimeClearedNode.isNull()) {
description.appendText("Time Cleared should be null");
return false;
}
}
final String jsonSeverity = jsonAlarm.get("severity").asText();
final String severity = alarm.severity().toString();
if (!severity.equals(jsonSeverity)) {
description.appendText("severity was " + jsonSeverity);
return false;
}
final JsonNode jsonAlarmNode = jsonAlarm.get("source");
if (alarm.source() != null) {
final String jsonSource = jsonAlarmNode.textValue();
final String source = alarm.source().toString();
if (!source.equals(jsonSource)) {
description.appendText("source was " + jsonSource);
return false;
}
} else {
// source not specified, JSON representation must be empty
if (!jsonAlarmNode.isNull()) {
description.appendText("source should be null");
return false;
}
}
// In progress
return true;
}
@Override
public void describeTo(final Description description) {
description.appendText(alarm.toString());
}
/**
* Factory to allocate a alarm matcher.
*
* @param alarm alarm object we are looking for
* @return matcher
*/
public static AlarmJsonMatcher matchesAlarm(final Alarm alarm) {
return new AlarmJsonMatcher(alarm);
}
}
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.faultmanagement.web;
import com.sun.jersey.api.client.WebResource;
import org.junit.Before;
import org.junit.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.not;
import org.junit.Ignore;
import org.onlab.osgi.ServiceDirectory;
import org.onlab.osgi.TestServiceDirectory;
import org.onlab.rest.BaseResource;
import org.onosproject.codec.CodecService;
import org.onosproject.codec.impl.CodecManager;
import org.onosproject.rest.ResourceTest;
/**
* Test of the Fault Management Web REST API for Alarms.
*/
public class AlarmsWebResourceTest extends ResourceTest {
@Before
public void setUp() {
final CodecManager codecService = new CodecManager();
codecService.activate();
final ServiceDirectory testDirectory
= new TestServiceDirectory()
// Currently no alarms-service implemented
// .add(AlarmsService.class, alarmsService)
.add(CodecService.class, codecService);
BaseResource.setServiceDirectory(testDirectory);
}
@Test
@Ignore
public void getAllAlarms() {
final WebResource rs = resource();
final String response = rs.path("/alarms").get(String.class);
// Ensure hard-coded alarms returned okay
assertThat(response, containsString("\"NE is not reachable\","));
assertThat(response, containsString("\"Equipment Missing\","));
}
@Test
@Ignore
public void getAlarm() {
final WebResource rs = resource();
final String response = rs.path("/alarms/1").get(String.class);
// Ensure hard-coded alarms returned okay
assertThat(response, containsString("\"NE is not reachable\","));
assertThat(response, not(containsString("\"Equipment Missing\",")));
}
}
{
"id": 10,
"deviceId": "of:123",
"description": "NE is not reachable",
"source": "none:none",
"timeRaised": 999,
"timeUpdated": 1111,
"timeUpdated": 1111,
"timeCleared": 2222,
"severity": "MAJOR",
"serviceAffecting": true,
"acknowledged": false,
"manuallyClearable": true,
"assignedUser": "foo"
}
\ No newline at end of file
{
"id": 10,
"deviceId": "of:123",
"description": "NE is not reachable",
"source": "none:none",
"timeRaised": 999,
"timeUpdated": 1111,
"severity": "MAJOR",
"serviceAffecting": true,
"acknowledged": false,
"manuallyClearable": true
}
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2014 Open Networking Laboratory
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.onosproject</groupId>
<artifactId>onos-apps</artifactId>
<version>1.4.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>onos-app-fm</artifactId>
<packaging>pom</packaging>
<description>ONOS framework applications</description>
<modules>
<module>fmmgr</module>
<module>fmweb</module>
<module>app</module>
</modules>
<dependencies>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onlab-junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava-testlib</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
......@@ -31,6 +31,7 @@
<modules>
<module>aaa</module>
<module>acl</module>
<module>faultmanagement</module>
<module>fwd</module>
<module>mobility</module>
<module>proxyarp</module>
......
/*
* Copyright 2014-2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.incubator.net.faultmanagement.alarm;
import org.onosproject.net.DeviceId;
/**
* Representation of an Alarm. At a given instant there can be only one alarm
* with the same deviceId + description + source combination.
*/
public interface Alarm {
/**
* Returns the unique alarm id within this ONOS instance.
*
* @return alarm identifier
*/
AlarmId id();
/**
* The device to which this alarm is related.
*
* @return a device id
*/
DeviceId deviceId();
/**
* Returns a description of alarm.
* <p>
* It may encapsulate Event Type as described by ITU Recommendation X.736
* ITU, Quoting https://tools.ietf.org/html/rfc3877 these include: other,
* communicationsAlarm, qualityOfServiceAlarm, processingErrorAlarm,
* equipmentAlarm, environmentalAlarm, integrityViolation,
* operationalViolation, physicalViolation,
* securityServiceOrMechanismViolation, timeDomainViolation
* <p>
* It may encapsulate Probable Cause as described by ITU Recommendation
* X.736 ITU, Quoting
* https://www.iana.org/assignments/ianaitualarmtc-mib/ianaitualarmtc-mib
* these include : aIS, callSetUpFailure, degradedSignal,
* farEndReceiverFailure, framingError, and hundreds more constants.
* <p>
* It may encapsulate a vendor-specific description of the underlying fault.
*
* @return description of alarm
*/
String description();
/**
* Returns an entity within the context of this alarm's device. It may be
* null if deviceId sufficiently identifies the location. As an example, the
* source may indicate a port number
*
* @return source of alarm within the alarm's referenced Device.
*/
AlarmEntityId source();
/**
* Returns the time when raised.
*
* @return time when raised, in milliseconds since start of epoch
*/
long timeRaised();
/**
* Returns time at which the alarm was updated most recently, due to some
* change in the device, or ONOS. If the alarm has been cleared, this is the
* time at which the alarm was cleared.
*
* @return time when last updated, in milliseconds since start of epoch
*/
long timeUpdated();
/**
* Returns the time when cleared. Null indicated no clear time, i.e. the
* alarm is still active.
*
* @return time when cleared, in milliseconds since start of epoch or null
* if uncleared.
*/
Long timeCleared();
/**
* Returns the severity. Note, that cleared alarms may have EITHER
* SeverityLevel = CLEARED, or may be not present; both scenarios should be
* handled.
*
* @return severity of the alarm
*/
SeverityLevel severity();
/**
* Returns true if alarm is service affecting Note: Whilst X.733 combines
* service-affecting state with severity (where severities of critical and
* major are deemed service-affecting) ONOS keeps these attributes separate.
*
* @return whether service affecting (true indicates it is)
*/
boolean serviceAffecting();
/**
* Returns a flag to indicate if this alarm has been acknowledged. All
* alarms are unacknowledged until and unless an ONOS user takes action to
* indicate so.
*
* @return whether alarm is currently acknowledged (true indicates it is)
*/
boolean acknowledged();
/**
* Returns a flag to indicate if this alarm is manually-cleared by a user action within ONOS. Some stateless events
* e.g. backup-failure or upgrade-failure, may be mapped by ONOS to alarms, and these may be deemed manually-
* clearable. The more typical case is that an alarm represents a persistent fault on or related to a device and
* such alarms are never manually clearable, i.e. a configuration or operational state must occur for the alarm to
* clear.
*
* @return whether it may be cleared by a user action (true indicates it is)
*/
boolean manuallyClearable();
/**
* Returns the user to whom this alarm is assigned; this is for future use
* and always returns null in this release. It is anticipated that in future ONOS
* releases, the existing JAAS user/key/role configuration will be extended
* to include a mechanism whereby some groups of users may allocate alarms
* to other users for bookkeeping and administrative purposes, and that ONOS
* will additionally provide a REST based mechanism, to retrieve from JAAS,
* the set of users to whom alarm assignment is possible for the current
* user.
*
* @return the assigned user; always null in this release.
*/
String assignedUser();
/**
* Represents the severity level on an alarm, as per ITU-T X.733
* specifications.
* <p>
* The precedence is as follows for : Critical &gt; Major &gt; Minor &gt; Warning.
*/
enum SeverityLevel {
/**
* From X.733: This indicates the clearing of one or more previously
* reported alarms. This alarm clears all alarms for this managed object
* that have the same Alarm type, Probable cause and Specific problems
* (if given). Multiple associated notifications may be cleared by using
* the Correlated notifications parameter (defined below). This
* Recommendation | International Standard does not require that the
* clearing of previously reported alarms be reported. Therefore, a
* managing system cannot assume that the absence of an alarm with the
* Cleared severity level means that the condition that caused the
* generation of previous alarms is still present. Managed object
* definers shall state if, and under which conditions, the Cleared
* severity level is used.
*/
CLEARED,
/**
* From X.733: This indicates that the severity level cannot be
* determined.
*/
INDETERMINATE,
/**
* From X.733: This indicates that a service affecting condition has
* occurred and an immediate corrective action is required. Such a
* severity can be reported, for example, when a managed object becomes
* totally out of service and its capability must be restored.
*/
CRITICAL,
/**
* X.733 definition: This indicates that a service affecting condition
* has developed and an urgent corrective action is required. Such a
* severity can be reported, for example, when there is a severe
* degradation in the capability of the managed object and its full
* capability must be restored.
*/
MAJOR,
/**
* From X.733: This indicates the existence of a non-service affecting
* fault condition and that corrective action should be taken in order
* to prevent a more serious (for example, service affecting) fault.
* Such a severity can be reported, for example, when the detected alarm
* condition is not currently degrading the capacity of the managed
* object.
*/
MINOR,
/**
* From X.733: This indicates the detection of a potential or impending
* service affecting fault, before any significant effects have been
* felt. Action should be taken to further diagnose (if necessary) and
* correct the problem in order to prevent it from becoming a more
* serious service affecting fault.
*/
WARNING;
}
}
/*
* Copyright 2014-2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.incubator.net.faultmanagement.alarm;
import static com.google.common.base.Preconditions.checkArgument;
import com.google.common.collect.ImmutableSet;
import java.net.URI;
import java.util.Objects;
import java.util.Set;
/**
* Immutable representation of a alarm source. It is meaningful within the
* context of a device.
*/
public final class AlarmEntityId {
public static final AlarmEntityId NONE = new AlarmEntityId(URI.create("none:none"));
public static final Set<String> SCHEMES = ImmutableSet.of("none", "port", "och", "other");
private final URI uri;
private AlarmEntityId(final URI uri) {
this.uri = uri;
}
protected AlarmEntityId() {
uri = NONE.uri;
}
public static AlarmEntityId alarmEntityId(final String string) {
return alarmEntityId(URI.create(string));
}
public static AlarmEntityId alarmEntityId(final URI uri) {
checkArgument(SCHEMES.contains(uri.getScheme()), "Unexpected scheme");
return new AlarmEntityId(uri);
}
@Override
public String toString() {
return uri.toString();
}
@Override
public int hashCode() {
return Objects.hash(uri);
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof AlarmEntityId) {
final AlarmEntityId other = (AlarmEntityId) obj;
return Objects.equals(this.uri, other.uri);
}
return false;
}
}
/*
* Copyright 2014 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.incubator.net.faultmanagement.alarm;
import org.onosproject.event.AbstractEvent;
/**
* Entity that represents Alarm events.
*/
public class AlarmEvent extends AbstractEvent<AlarmEvent.Type, Alarm> {
/**
* Creates an event of a given type and for the specified alarm and the
* current time.
*
* @param type topology event type
* @param alarm the alarm
*/
public AlarmEvent(Type type, Alarm alarm) {
super(type, alarm);
}
/**
* Creates an event of a given type and for the specified alarm and time.
*
* @param type link event type
* @param alarm the alarm
* @param time occurrence time
*/
public AlarmEvent(Type type, Alarm alarm,
long time) {
super(type, alarm, time);
}
/**
* Type of alarm events.
*/
public enum Type {
/**
* A Raised Alarm.
*/
RAISE,
/**
* A Cleared Alarm.
*/
CLEAR
}
}
/*
* Copyright 2014 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.incubator.net.faultmanagement.alarm;
import com.google.common.annotations.Beta;
import java.util.Objects;
import static com.google.common.base.MoreObjects.toStringHelper;
/**
* Alarm identifier suitable as an external key.
* <p>
* This class is immutable.</p>
*/
@Beta
public final class AlarmId {
private final long id;
/**
* Instantiates a new Alarm id.
*
* @param id the id
*/
public AlarmId(final long id) {
this.id = id;
}
/**
* Creates an alarm identifier from the specified long representation.
*
* @param value long value
* @return intent identifier
*/
public static AlarmId valueOf(final long value) {
return new AlarmId(value);
}
/**
* Returns the backing integer index.
*
* @return backing integer index
*/
public long fingerprint() {
return id;
}
@Override
public int hashCode() {
return Objects.hash(id);
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof AlarmId) {
final AlarmId other = (AlarmId) obj;
return Objects.equals(this.id, other.id);
}
return false;
}
@Override
public String toString() {
return toStringHelper(this).add("id", id).toString();
}
}
/*
* Copyright 2014 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.incubator.net.faultmanagement.alarm;
import org.onosproject.event.EventListener;
/**
* Entity capable of receiving Alarm related events.
*/
public interface AlarmListener extends EventListener<AlarmEvent> {
}
/*
* Copyright 2014 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.incubator.net.faultmanagement.alarm;
import org.onosproject.net.DeviceId;
import org.onosproject.net.provider.Provider;
/**
* Abstraction of a Alarm provider.
*/
public interface AlarmProvider extends Provider {
/**
* Triggers an asynchronous discovery of the alarms on the specified device,
* intended to refresh internal alarm model for the device. An indirect
* result of this should be invocation of
* {@link org.onosproject.incubator.net.faultmanagement.alarm.AlarmProviderService#updateAlarmList} )}
* at some later point in time.
*
* @param deviceId ID of device to be probed
*/
void triggerProbe(DeviceId deviceId);
}
/*
* Copyright 2014 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.incubator.net.faultmanagement.alarm;
import org.onosproject.net.provider.ProviderRegistry;
/**
* Abstraction of a alarm provider registry.
*/
public interface AlarmProviderRegistry extends ProviderRegistry<AlarmProvider, AlarmProviderService> {
}
/*
* Copyright 2014 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.incubator.net.faultmanagement.alarm;
import org.onosproject.net.DeviceId;
import org.onosproject.net.provider.ProviderService;
import java.util.Collection;
/**
* The interface Alarm provider service.
*/
public interface AlarmProviderService extends ProviderService<AlarmProvider> {
/**
* Sends active alarm list for a device.
*
* @param deviceId identity of the device
* @param alarms list of device alarms
*/
void updateAlarmList(DeviceId deviceId, Collection<Alarm> alarms);
}
/*
* Copyright 2014-2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.incubator.net.faultmanagement.alarm;
import com.google.common.annotations.Beta;
//import org.onosproject.event.ListenerService;
import java.util.Set;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DeviceId;
/**
* Service for interacting with the alarm handling of devices. Unless stated
* otherwise method return active AND recently-cleared alarms.
*/
@Beta
public interface AlarmService {
// extends ListenerService<AlarmEvent, AlarmListener> {
/**
* Alarm should be updated in ONOS's internal representation; only
* administration/book-keeping fields may be updated. Attempting to update
* fields which are mapped directly from device is prohibited.
*
* @param replacement alarm with updated book-keeping fields
* @return updated alarm (including any recent device derived changes)
* @throws java.lang.IllegalStateException if attempt to update not allowed
* fields.
*/
Alarm update(Alarm replacement);
/**
* Returns the number of ACTIVE alarms on a device.
*
* @param deviceId the device
* @return number of alarms
*/
int getActiveAlarmCount(DeviceId deviceId);
/**
* Returns the alarm with the specified identifier.
*
* @param alarmId alarm identifier
* @return alarm or null if one with the given identifier is not known
*/
Alarm getAlarm(AlarmId alarmId);
/**
* Returns all of the alarms.
*
* @return the alarms
*/
Set<Alarm> getAlarms();
/**
* Returns all of the ACTIVE alarms. Recently cleared alarms excluded.
*
* @return the alarms
*/
Set<Alarm> getActiveAlarms();
/**
* Returns the alarms with the specified severity.
*
* @param severity the alarm severity
* @return the active alarms with a particular severity
*/
Set<Alarm> getAlarms(Alarm.SeverityLevel severity);
/**
* Returns the alarm for a given device, regardless of source within that
* device.
*
* @param deviceId the device
* @return the alarms
*/
Set<Alarm> getAlarms(DeviceId deviceId);
/**
* Returns the alarm for a given device and source.
*
* @param deviceId the device
* @param source the source within the device
* @return the alarms
*/
Set<Alarm> getAlarms(DeviceId deviceId, AlarmEntityId source);
/**
* Returns the alarm affecting a given link.
*
* @param src one end of the link
* @param dst one end of the link
* @return the alarms
*/
Set<Alarm> getAlarmsForLink(ConnectPoint src, ConnectPoint dst);
/**
* Returns the alarm affecting a given flow.
*
* @param deviceId the device
* @param flowId the flow
* @return the alarms
*/
Set<Alarm> getAlarmsForFlow(DeviceId deviceId, long flowId);
// Support retrieving alarms affecting other ONOS entity types may be added in future release
}
/*
* Copyright 2014-2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.incubator.net.faultmanagement.alarm;
import org.onosproject.net.DeviceId;
import java.util.Objects;
import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Default implementation of an alarm.
*/
public final class DefaultAlarm implements Alarm {
private final AlarmId id;
private final DeviceId deviceId;
private final String description;
private final AlarmEntityId source;
private final long timeRaised;
private final long timeUpdated;
private final Long timeCleared;
private final SeverityLevel severity;
private final boolean isServiceAffecting;
private final boolean isAcknowledged;
private final boolean isManuallyClearable;
private final String assignedUser;
/**
* Instantiates a new Default alarm.
*
* @param id the id
* @param deviceId the device id
* @param description the description
* @param source the source, null indicates none.
* @param timeRaised the time raised.
* @param timeUpdated the time last updated.
* @param timeCleared the time cleared, null indicates uncleared.
* @param severity the severity
* @param isServiceAffecting the service affecting
* @param isAcknowledged the acknowledged
* @param isManuallyClearable the manually clearable
* @param assignedUser the assigned user, `null` indicates none.
*/
private DefaultAlarm(final AlarmId id,
final DeviceId deviceId,
final String description,
final AlarmEntityId source,
final long timeRaised,
final long timeUpdated,
final Long timeCleared,
final SeverityLevel severity,
final boolean isServiceAffecting,
final boolean isAcknowledged,
final boolean isManuallyClearable,
final String assignedUser) {
this.id = id;
this.deviceId = deviceId;
this.description = description;
this.source = source;
this.timeRaised = timeRaised;
this.timeUpdated = timeUpdated;
this.timeCleared = timeCleared;
this.severity = severity;
this.isServiceAffecting = isServiceAffecting;
this.isAcknowledged = isAcknowledged;
this.isManuallyClearable = isManuallyClearable;
this.assignedUser = assignedUser;
}
@Override
public AlarmId id() {
return id;
}
@Override
public DeviceId deviceId() {
return deviceId;
}
@Override
public String description() {
return description;
}
@Override
public AlarmEntityId source() {
return source;
}
@Override
public long timeRaised() {
return timeRaised;
}
@Override
public long timeUpdated() {
return timeUpdated;
}
@Override
public Long timeCleared() {
return timeCleared;
}
@Override
public SeverityLevel severity() {
return severity;
}
@Override
public boolean serviceAffecting() {
return isServiceAffecting;
}
@Override
public boolean acknowledged() {
return isAcknowledged;
}
@Override
public boolean manuallyClearable() {
return isManuallyClearable;
}
@Override
public String assignedUser() {
return assignedUser;
}
@Override
public int hashCode() {
return Objects.hash(id, deviceId, description,
source, timeRaised, timeUpdated, timeCleared, severity,
isServiceAffecting, isAcknowledged,
isManuallyClearable, assignedUser);
}
@Override
public boolean equals(final Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final DefaultAlarm other = (DefaultAlarm) obj;
if (!Objects.equals(this.id, other.id)) {
return false;
}
if (!Objects.equals(this.deviceId, other.deviceId)) {
return false;
}
if (!Objects.equals(this.description, other.description)) {
return false;
}
if (!Objects.equals(this.source, other.source)) {
return false;
}
if (this.timeRaised != other.timeRaised) {
return false;
}
if (this.timeUpdated != other.timeUpdated) {
return false;
}
if (!Objects.equals(this.timeCleared, other.timeCleared)) {
return false;
}
if (this.severity != other.severity) {
return false;
}
if (this.isServiceAffecting != other.isServiceAffecting) {
return false;
}
if (this.isAcknowledged != other.isAcknowledged) {
return false;
}
if (this.isManuallyClearable != other.isManuallyClearable) {
return false;
}
if (!Objects.equals(this.assignedUser, other.assignedUser)) {
return false;
}
return true;
}
@Override
public String toString() {
return toStringHelper(this)
.add("id", id)
.add("deviceId", deviceId)
.add("description", description)
.add("source", source)
.add("timeRaised", timeRaised)
.add("timeUpdated", timeUpdated)
.add("timeCleared", timeCleared)
.add("severity", severity)
.add("serviceAffecting", isServiceAffecting)
.add("acknowledged", isAcknowledged)
.add("manuallyClearable", isManuallyClearable)
.add("assignedUser", assignedUser)
.toString();
}
public static class Builder {
// Manadatory fields ..
private final AlarmId id;
private final DeviceId deviceId;
private final String description;
private final SeverityLevel severity;
private final long timeRaised;
// Optional fields ..
private AlarmEntityId source = AlarmEntityId.NONE;
private long timeUpdated;
private Long timeCleared = null;
private boolean isServiceAffecting = false;
private boolean isAcknowledged = false;
private boolean isManuallyClearable = false;
private String assignedUser = null;
public Builder(final Alarm alarm) {
this(alarm.id(), alarm.deviceId(), alarm.description(), alarm.severity(), alarm.timeRaised());
this.source = AlarmEntityId.NONE;
this.timeUpdated = alarm.timeUpdated();
this.timeCleared = alarm.timeCleared();
this.isServiceAffecting = alarm.serviceAffecting();
this.isAcknowledged = alarm.acknowledged();
this.isManuallyClearable = alarm.manuallyClearable();
this.assignedUser = alarm.assignedUser();
}
public Builder(final AlarmId id, final DeviceId deviceId,
final String description, final SeverityLevel severity, final long timeRaised) {
super();
this.id = id;
this.deviceId = deviceId;
this.description = description;
this.severity = severity;
this.timeRaised = timeRaised;
// Unless specified time-updated is same as raised.
this.timeUpdated = timeRaised;
}
public Builder forSource(final AlarmEntityId source) {
this.source = source;
return this;
}
public Builder withTimeUpdated(final long timeUpdated) {
this.timeUpdated = timeUpdated;
return this;
}
public Builder withTimeCleared(final Long timeCleared) {
this.timeCleared = timeCleared;
return this;
}
public Builder withServiceAffecting(final boolean isServiceAffecting) {
this.isServiceAffecting = isServiceAffecting;
return this;
}
public Builder withAcknowledged(final boolean isAcknowledged) {
this.isAcknowledged = isAcknowledged;
return this;
}
public Builder withManuallyClearable(final boolean isManuallyClearable) {
this.isManuallyClearable = isManuallyClearable;
return this;
}
public Builder withAssignedUser(final String assignedUser) {
this.assignedUser = assignedUser;
return this;
}
public DefaultAlarm build() {
checkNotNull(id, "Must specify an alarm id");
checkNotNull(deviceId, "Must specify a device");
checkNotNull(description, "Must specify a description");
checkNotNull(timeRaised, "Must specify a time raised");
checkNotNull(timeUpdated, "Must specify a time updated");
checkNotNull(severity, "Must specify a severity");
return new DefaultAlarm(id, deviceId, description, source, timeRaised, timeUpdated, timeCleared,
severity, isServiceAffecting, isAcknowledged, isManuallyClearable, assignedUser);
}
}
}
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Abstractions for interacting with alarms. An alarm is a persistent indication
* of a fault that clears only when the triggering condition has been resolved.
*/
package org.onosproject.incubator.net.faultmanagement.alarm;
/*
* Copyright 2014-2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.incubator.net.faultmanagement.alarm;
import com.google.common.testing.EqualsTester;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
import static org.onosproject.incubator.net.faultmanagement.alarm.AlarmEntityId.alarmEntityId;
/**
* Test of the alarm source identifier.
*
*/
public class AlarmEntityIdTest {
/**
* Checks that the class is immutable.
*/
@Test
public void testImmutability() {
assertThatClassIsImmutable(AlarmEntityId.class);
}
@Test
public void string() {
assertEquals("och:foo",
alarmEntityId("och:foo").toString());
}
@Test
public void basics() {
new EqualsTester()
.addEqualityGroup(
alarmEntityId("och:foo"),
alarmEntityId("och:foo"))
.addEqualityGroup(alarmEntityId("och:bar"))
.testEquals();
}
@Test
public void validSchemaPermitted() {
alarmEntityId("none:foo");
alarmEntityId("port:foo");
alarmEntityId("och:foo");
alarmEntityId("other:foo");
}
@Test(expected = IllegalArgumentException.class)
public void verifyUnexpectedSchemaRejected() {
alarmEntityId("junk:foo");
}
@Test(expected = IllegalArgumentException.class)
public void verifyCorruptSchemaRejected() {
alarmEntityId("other:");
}
}
/*
* Copyright 2014 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.incubator.net.faultmanagement.alarm;
import com.google.common.testing.EqualsTester;
import org.junit.Test;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
/**
* This class tests the immutability, equality, and non-equality of
* {@link AlarmId}.
*/
public class AlarmIdTest {
private static final long ID_A = 1L;
private static final long ID_B = 2L;
private static final long ID_Z = 987654321L;
/**
* Tests the immutability of {@link AlarmId}.
*/
@Test
public void intentIdFollowsGuidelineForImmutableObject() {
assertThatClassIsImmutable(AlarmId.class);
}
/**
* Tests equality of {@link AlarmId}.
*/
@Test
public void testEquality() {
final AlarmId id1 = new AlarmId(ID_A);
final AlarmId id2 = new AlarmId(ID_A);
assertThat(id1, is(id2));
}
/**
* Tests non-equality of {@link AlarmId}.
*/
@Test
public void testNonEquality() {
final AlarmId id1 = new AlarmId(ID_A);
final AlarmId id2 = new AlarmId(ID_B);
assertThat(id1, is(not(id2)));
}
@Test
public void valueOf() {
final AlarmId id = new AlarmId(0xdeadbeefL);
assertEquals("incorrect valueOf", id, AlarmId.valueOf(0xdeadbeefL));
}
/**
* Tests the equals(), hashCode() and toString() methods.
*/
@Test
public void testEquals() {
final AlarmId id1 = new AlarmId(11111L);
final AlarmId sameAsId1 = new AlarmId(11111L);
final AlarmId id2 = new AlarmId(22222L);
new EqualsTester()
.addEqualityGroup(id1, sameAsId1)
.addEqualityGroup(id2)
.testEquals();
}
/**
* Tests construction of an AlarmId object.
*/
@Test
public void testConstruction() {
final AlarmId id1 = new AlarmId(ID_Z);
assertEquals(id1.fingerprint(), ID_Z);
// No default constructor so no need to test it !
}
}
/*
* Copyright 2014 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.incubator.net.faultmanagement.alarm;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import org.junit.Test;
import static org.junit.Assert.*;
import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
import org.onosproject.net.DeviceId;
public class DefaultAlarmTest {
@Test
public void testImmutability() {
assertThatClassIsImmutable(DefaultAlarm.class);
}
/**
* Checks the construction of a DefaultAlarm object.
*/
@Test
public void testConstruction() {
final String nameValue = "name3";
final DefaultAlarm a = new DefaultAlarm.Builder(AlarmId.valueOf(4),
DeviceId.NONE, nameValue, Alarm.SeverityLevel.CLEARED, 3).build();
assertThat(a, is(notNullValue()));
final DefaultAlarm b = new DefaultAlarm.Builder(a).build();
assertEquals(a, b);
}
}
......@@ -41,6 +41,7 @@
<module>pcep</module>
<module>ovsdb</module>
<module>bgp</module>
<module>snmp</module>
</modules>
<dependencies>
......
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2014 Open Networking Laboratory
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.onosproject</groupId>
<artifactId>onos-snmp-providers</artifactId>
<version>1.4.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>onos-snmp-provider-alarm</artifactId>
<packaging>bundle</packaging>
<description>ONOS SNMP protocol alarm provider</description>
</project>
\ No newline at end of file
/*
* Copyright 2014-2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.provider.snmp.alarm.impl;
import org.apache.felix.scr.annotations.Component;
import org.onosproject.net.DeviceId;
import org.onosproject.incubator.net.faultmanagement.alarm.AlarmProvider;
import org.onosproject.net.provider.AbstractProvider;
import org.onosproject.net.provider.ProviderId;
import org.slf4j.Logger;
import static org.slf4j.LoggerFactory.getLogger;
/**
* Provider which uses an SNMP controller to detect network device alarms. The class leverages functionality from
*
* @see <a href="https://github.com/btisystems/snmp-core">https://github.com/btisystems/snmp-core</a>
* @see <a href="https://github.com/btisystems/mibbler">https://github.com/btisystems/mibbler</a>
*/
@Component(immediate = true)
public class SNMPAlarmProvider extends AbstractProvider implements AlarmProvider {
private static final Logger LOG = getLogger(SNMPAlarmProvider.class);
/**
* Creates a SNMP alarm provider, dummy class provided as template, tbd later.
*/
public SNMPAlarmProvider() {
super(new ProviderId("snmp", "org.onosproject.provider.alarm"));
}
@Override
public void triggerProbe(final DeviceId deviceId) {
// TODO in shout term should this just be synchronous and return result?
LOG.info("Run a SNMP discovery for device at {} when done invoke on AlarmProviderService", deviceId);
// TODO Look up AlarmProviderService
// TODO Decide threading
// TODO Decide shouldn't it be generic not alarm-specific ? Its user responsible for passing in OID list ?
// Same for its callack AlarmProviderService ?
}
}
/*
* Copyright 2014 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Provider that uses SNMP as a means of discovering alarms on devices.
*/
package org.onosproject.provider.snmp.alarm.impl;
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2014 Open Networking Laboratory
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.onosproject</groupId>
<artifactId>onos-providers</artifactId>
<version>1.4.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>onos-snmp-providers</artifactId>
<packaging>pom</packaging>
<description>ONOS SNMP Protocol Adapters</description>
<modules>
<module>alarm</module>
</modules>
</project>
\ No newline at end of file
#
# devices which may have faults.
# TODO change to NetworkConfig subsystem.
#
fmDevices = 172.27.7.110,172.27.7.110,3.3.3.3