/******************************************************************************* * This file is part of OpenNMS(R). * * Copyright (C) 2008-2011 The OpenNMS Group, Inc. * OpenNMS(R) is Copyright (C) 1999-2011 The OpenNMS Group, Inc. * * OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc. * * OpenNMS(R) is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published * by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * OpenNMS(R) 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenNMS(R). If not, see: * http://www.gnu.org/licenses/ * * For more information contact: * OpenNMS(R) Licensing <license@opennms.org> * http://www.opennms.org/ * http://www.opennms.com/ *******************************************************************************/ package org.opennms.netmgt.ncs.rest; import java.util.Collection; import java.util.LinkedList; import java.util.List; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantReadWriteLock; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; import javax.ws.rs.core.UriInfo; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import org.opennms.core.utils.LogUtils; import org.opennms.netmgt.dao.AlarmDao; import org.opennms.netmgt.dao.EventDao; import org.opennms.netmgt.model.ncs.NCSComponent; import org.opennms.netmgt.ncs.persistence.NCSComponentService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.dao.DataAccessException; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.Assert; import com.sun.jersey.spi.resource.PerRequest; /** * Basic Web Service using REST for NCS Components * * @author <a href="mailto:brozow@opennms.org">Matt Brozowski</a> */ @Component @PerRequest @Scope("prototype") @Path("NCS") @Transactional public class NCSRestService { @Autowired NCSComponentService m_componentService; @Autowired EventDao m_eventDao; @Autowired AlarmDao m_alarmDao; @Context UriInfo m_uriInfo; public void afterPropertiesSet() throws RuntimeException { Assert.notNull(m_componentService); Assert.notNull(m_eventDao); Assert.notNull(m_alarmDao); } /** * <p>getNodes</p> * * @return a {@link org.opennms.netmgt.model.OnmsNodeList} object. */ @GET @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) @Path("{type}/{foreignSource}:{foreignId}") public NCSComponent getComponent(@PathParam("type") final String type, @PathParam("foreignSource") final String foreignSource, @PathParam("foreignId") final String foreignId) { afterPropertiesSet(); readLock(); try { LogUtils.debugf(this, "getComponent: type = %s, foreignSource = %s, foreignId = %s", type, foreignSource, foreignId); if (m_componentService == null) { throw new IllegalStateException("component service is null"); } final NCSComponent component = m_componentService.getComponent(type, foreignSource, foreignId); if (component == null) throw new WebApplicationException(Status.BAD_REQUEST); return component; } finally { readUnlock(); } } @GET @Path("attributes") public ComponentList getComponentsByAttributes() { afterPropertiesSet(); readLock(); try { if (m_componentService == null) { throw new IllegalStateException("component service is null"); } return m_componentService.findComponentsWithAttribute("jnxVpnPwVpnName", "ge-3/1/4.2"); } finally { readUnlock(); } } @POST @Consumes(MediaType.APPLICATION_XML) public Response addComponents(@QueryParam("deleteOrphans") final boolean deleteOrphans, final NCSComponent component) { afterPropertiesSet(); writeLock(); try { LogUtils.debugf(this, "addComponents: Adding component %s (deleteOrphans=%s)", component, Boolean.valueOf(deleteOrphans)); if (m_componentService == null) { throw new IllegalStateException("component service is null"); } try { m_componentService.addOrUpdateComponents(component, deleteOrphans); } catch (final DataAccessException e) { throw new WebApplicationException(e, Status.BAD_REQUEST); } return Response.ok(component).build(); } finally { writeUnlock(); } } /** * <p>getNodes</p> * * @return a {@link org.opennms.netmgt.model.OnmsNodeList} object. */ @POST @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) @Path("{type}/{foreignSource}:{foreignId}") public NCSComponent addComponent(@QueryParam("deleteOrphans") final boolean deleteOrphans, @PathParam("type") String type, @PathParam("foreignSource") String foreignSource, @PathParam("foreignId") String foreignId, NCSComponent subComponent) { afterPropertiesSet(); writeLock(); try { LogUtils.debugf(this, "addComponent: type = %s, foreignSource = %s, foreignId = %s (deleteOrphans=%s)", type, foreignSource, foreignId, Boolean.valueOf(deleteOrphans)); if (m_componentService == null) { throw new IllegalStateException("component service is null"); } if (subComponent == null) { throw new WebApplicationException(Status.BAD_REQUEST); } try { return m_componentService.addSubcomponent(type, foreignSource, foreignId, subComponent, deleteOrphans); } catch (final DataAccessException e) { throw new WebApplicationException(e, Status.BAD_REQUEST); } } finally { writeUnlock(); } } @DELETE @Path("{type}/{foreignSource}:{foreignId}") public Response deleteComponent(@QueryParam("deleteOrphans") final boolean deleteOrphans, @PathParam("type") String type, @PathParam("foreignSource") String foreignSource, @PathParam("foreignId") String foreignId) { afterPropertiesSet(); writeLock(); try { LogUtils.infof(this, "deleteComponent: Deleting component of type %s and foreignIdentity %s:%s (deleteOrphans=%s)", type, foreignSource, foreignId, Boolean.valueOf(deleteOrphans)); if (m_componentService == null) { throw new IllegalStateException("component service is null"); } m_componentService.deleteComponent(type, foreignSource, foreignId, deleteOrphans); return Response.ok().build(); } finally { writeUnlock(); } } private final ReentrantReadWriteLock m_globalLock = new ReentrantReadWriteLock(); private final Lock m_readLock = m_globalLock.readLock(); private final Lock m_writeLock = m_globalLock.writeLock(); protected void readLock() { m_readLock.lock(); } protected void readUnlock() { if (m_globalLock.getReadHoldCount() > 0) { m_readLock.unlock(); } } protected void writeLock() { if (m_globalLock.getWriteHoldCount() == 0) { while (m_globalLock.getReadHoldCount() > 0) { m_readLock.unlock(); } m_writeLock.lock(); } } protected void writeUnlock() { if (m_globalLock.getWriteHoldCount() > 0) { m_writeLock.unlock(); } } @XmlRootElement(name = "components") public static class ComponentList extends LinkedList<NCSComponent> { private static final long serialVersionUID = 8031737923157780179L; private int m_totalCount; /** * <p>Constructor for OnmsNodeList.</p> */ public ComponentList() { super(); } /** * <p>Constructor for OnmsNodeList.</p> * * @param c a {@link java.util.Collection} object. */ public ComponentList(Collection<? extends NCSComponent> c) { super(c); } /** * <p>getNodes</p> * * @return a {@link java.util.List} object. */ @XmlElement(name = "component") public List<NCSComponent> getComponents() { return this; } /** * <p>setNodes</p> * * @param components a {@link java.util.List} object. */ public void setComponents(List<NCSComponent> components) { clear(); addAll(components); } /** * <p>getCount</p> * * @return a {@link java.lang.Integer} object. */ @XmlAttribute(name="count") public int getCount() { return this.size(); } // The property has a getter "" but no setter. For unmarshalling, please define setters. public void setCount(final int count) { } /** * <p>getTotalCount</p> * * @return a int. */ @XmlAttribute(name="totalCount") public int getTotalCount() { return m_totalCount; } /** * <p>setTotalCount</p> * * @param count a int. */ public void setTotalCount(int count) { m_totalCount = count; } } }