blob: 56d5598527ebb9375674ff97802882565ef88c85 [file] [log] [blame]
/*
* Copyright 2021-present Open Networking Foundation
*
* 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.opencord.pppoeagent.rest;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.util.Map;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.onlab.packet.MacAddress;
import org.onlab.packet.PPPoED;
import org.onlab.util.ItemNotFoundException;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.Port;
import org.onosproject.rest.AbstractWebResource;
import org.opencord.pppoeagent.impl.PppoeAgentCounterNames;
import org.opencord.pppoeagent.impl.PppoeAgentCountersStore;
import org.opencord.pppoeagent.impl.PppoeAgentCountersIdentifier;
import org.opencord.pppoeagent.impl.PppoeAgentStatistics;
import org.opencord.pppoeagent.PppoeAgentEvent;
import org.opencord.pppoeagent.PppoeAgentService;
import org.opencord.pppoeagent.PppoeSessionInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;
/**
* PppoeAgent web resource.
*/
@Path("pppoeagent-app")
public class PppoeAgentWebResource extends AbstractWebResource {
private final ObjectNode root = mapper().createObjectNode();
private final ArrayNode node = root.putArray("entry");
private static final String SESSION_NOT_FOUND = "Session not found";
private final Logger log = LoggerFactory.getLogger(getClass());
DeviceService deviceService = AbstractShellCommand.get(DeviceService.class);
/**
* Get session info object.
*
* @param mac Session MAC address
*
* @return 200 OK
*/
@GET
@Path("/session/{mac}")
@Produces(MediaType.APPLICATION_JSON)
public Response getSubscriber(@PathParam("mac") String mac) {
MacAddress macAddress = MacAddress.valueOf(mac);
PppoeAgentService pppoeAgent = get(PppoeAgentService.class);
PppoeSessionInfo entry = pppoeAgent.getSessionsMap().get(macAddress);
if (entry == null) {
throw new ItemNotFoundException(SESSION_NOT_FOUND);
}
try {
node.add(encodePppoeSessionInfo(entry, macAddress));
return ok(mapper().writeValueAsString(root)).build();
} catch (IllegalArgumentException e) {
log.error("Error while fetching PPPoE session info for MAC {} through REST API: {}", mac, e.getMessage());
return Response.status(INTERNAL_SERVER_ERROR).build();
} catch (JsonProcessingException e) {
log.error("Error assembling JSON response for PPPoE session info request for MAC {} " +
"through REST API: {}", mac, e.getMessage());
return Response.status(INTERNAL_SERVER_ERROR).build();
}
}
/**
* Get all session info objects.
*
* @return 200 OK
*/
@GET
@Path("/session")
@Produces(MediaType.APPLICATION_JSON)
public Response getSubscribers() {
try {
PppoeAgentService pppoeAgent = get(PppoeAgentService.class);
pppoeAgent.getSessionsMap().forEach((mac, entry) -> {
node.add(encodePppoeSessionInfo(entry, mac));
});
return ok(mapper().writeValueAsString(root)).build();
} catch (Exception e) {
log.error("Error while fetching PPPoE sessions information through REST API: {}", e.getMessage());
return Response.status(INTERNAL_SERVER_ERROR).build();
}
}
private ObjectNode encodePppoeSessionInfo(PppoeSessionInfo entry, MacAddress macAddress) {
ConnectPoint cp = entry.getClientCp();
Port devicePort = deviceService.getPort(cp);
String portLabel = "uni-" + ((cp.port().toLong() & 0xF) + 1);
String subscriberId = devicePort != null ? devicePort.annotations().value(AnnotationKeys.PORT_NAME) :
"UNKNOWN";
return mapper().createObjectNode()
.put("macAddress", macAddress.toString())
.put("sessionId", entry.getSessionId())
.put("currentState", entry.getCurrentState())
.put("lastReceivedPacket", PPPoED.Type.getTypeByValue(entry.getPacketCode()).name())
.put("deviceId", cp.deviceId().toString())
.put("portNumber", cp.port().toString())
.put("portLabel", portLabel)
.put("subscriberId", subscriberId);
}
/**
* Gets PPPoE Agent counters for global context.
*
* @return 200 OK
*/
@GET
@Path("/stats")
@Produces(MediaType.APPLICATION_JSON)
public Response getPppoeStats() {
return getStats(PppoeAgentEvent.GLOBAL_COUNTER);
}
/**
* Gets PPPoE Agent counters for specific subscriber.
*
* @param subscriberId Id of subscriber.
*
* @return 200 OK
*/
@GET
@Path("/stats/{subscriberId}")
@Produces(MediaType.APPLICATION_JSON)
public Response getPppoeSubscriberStats(@PathParam("subscriberId") String subscriberId) {
return getStats(subscriberId);
}
private Response getStats(String key) {
PppoeAgentCountersStore pppoeCounters = get(PppoeAgentCountersStore.class);
try {
PppoeAgentStatistics pppoeStatistics = pppoeCounters.getCounters();
JsonNode completeNode = buildPppoeCounterNodeObject(key, pppoeStatistics.counters());
return ok(mapper().writeValueAsString(completeNode)).build();
} catch (JsonProcessingException e) {
log.error("Error while fetching PPPoE agent counter stats through REST API: {}", e.getMessage());
return Response.status(INTERNAL_SERVER_ERROR).build();
}
}
private JsonNode buildPppoeCounterNodeObject(String key, Map<PppoeAgentCountersIdentifier, Long> countersMap) {
ObjectNode entryNode = mapper().createObjectNode();
for (PppoeAgentCounterNames counterType : PppoeAgentCounterNames.SUPPORTED_COUNTERS) {
Long value = countersMap.get(new PppoeAgentCountersIdentifier(key, counterType));
if (value == null) {
continue;
}
entryNode = entryNode.put(counterType.name(), String.valueOf(value));
}
return mapper().createObjectNode().set(key, entryNode);
}
}