Skip to content
This repository was archived by the owner on Mar 24, 2023. It is now read-only.

Commit 1b8485c

Browse files
authored
Merge pull request #12 from ehrnst/dev
Dev
2 parents 26e5a03 + cad3f79 commit 1b8485c

File tree

7 files changed

+281
-29
lines changed

7 files changed

+281
-29
lines changed

README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@ Bringing SCOM in to the 21. century with a Restful Web API.
2222
| ------ | ------ |
2323
| [GET] API/Alerts | Gets all open alerts |
2424
| [GET] API/Alert/{id} | Get a single alert |
25-
| [PUT] API/Alert | Update the specified alert with resolution state, TicketId |
26-
| [GET] API/Alert/{ComputerName} | Get all alert from specific computer, use IncClosed=true to include open and closed alerts |
25+
| [PUT] API/Alerts/{id} | Update the specified alert with common properties and resolution state |
26+
| [GET] API/Alert/Computer/{ComputerName} | Get all alert from specific computer, use IncClosed=true to include open and closed alerts |
27+
| [GET] API/Alert/MonitoringObject/{MonitoringObjectId} | Get all alert from specific monitoring object, use IncClosed=true to include open and closed alerts |
2728

2829
### Computer
2930

@@ -50,6 +51,7 @@ Bringing SCOM in to the 21. century with a Restful Web API.
5051
| Route | Description |
5152
| ------ | ------ |
5253
| [GET] API/MonitoringObject/{id} | Get a monitoring object and all child object |
54+
| [GET] API/MonitoringObject/class/{classId} | Get all objects of a class. Limited properties returned. |
5355

5456

5557
### Installation
@@ -59,3 +61,6 @@ Bringing SCOM in to the 21. century with a Restful Web API.
5961
- Set your application pool to use Network Service
6062
- Enable windows authentication (basic if needed)
6163
- Copy SCOM specific .dll's to the BIN folder where you extracted the .Zip
64+
65+
### Remarks
66+
- Please note that versioning isn't implemented and current version have breaking changes to Alert endpoints. Please review the changes to get an understanding on how this affects your application. For first time users this is not a problem.

SCOM API/App_Start/WebApiConfig.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@ public static void Register(HttpConfiguration config)
1313
// Web API routes
1414
config.MapHttpAttributeRoutes();
1515

16+
1617
config.Routes.MapHttpRoute(
1718
name: "System Center Operations Manager API",
1819
routeTemplate: "API/{controller}/{action}/{id}",
1920
defaults: new { id = RouteParameter.Optional }
2021
);
2122

23+
2224
// Web API configuration and services
2325
config.Filters.Add(new AuthorizeAttribute());
2426

SCOM API/Controllers/SCOMAlertController.cs

Lines changed: 96 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
using System.Collections.ObjectModel;
1515
using Swashbuckle.AspNetCore.SwaggerGen;
1616
using System.Web.Http.Description;
17+
using SCOM_API.Models;
1718

1819
namespace SCOM_API.Controllers
1920
{
@@ -79,7 +80,7 @@ public IList<MonitoringAlert> GetAlertById(Guid Id)
7980
/// <param name="ComputerName">FQDN of the windows computer</param>
8081
/// <param name="IncClosed">if true closed alert is also returned. Default is 'false'</param>
8182
[HttpGet]
82-
[Route("Alerts/{ComputerName}")]
83+
[Route("Alerts/Computer/{ComputerName}")]
8384
public IList<MonitoringAlert> GetAlertByComputerName(string ComputerName, bool? IncClosed = false)
8485
{
8586
if (string.IsNullOrEmpty(ComputerName))
@@ -93,7 +94,7 @@ public IList<MonitoringAlert> GetAlertByComputerName(string ComputerName, bool?
9394
{
9495
//Set alert criteria
9596
var Criteria = string.Format("MonitoringObjectPath = '{0}'", ComputerName);
96-
///Get alerts
97+
//Get alerts
9798
MonitoringAlertCriteria alertCriteria = new MonitoringAlertCriteria(Criteria);
9899
var Alert = mg.OperationalData.GetMonitoringAlerts(alertCriteria, default(DateTime));
99100

@@ -113,31 +114,74 @@ public IList<MonitoringAlert> GetAlertByComputerName(string ComputerName, bool?
113114
}
114115

115116
/// <summary>
116-
/// Updates the specified alert.
117+
/// Get all alerts related to the specific monitoring object.
117118
/// </summary>
118-
/// <param name="ResolutionState">If specified as 255 (closed) and alert is raised by monitor. The corresponding monitor will be reset</param>
119-
/// <param name="TicketId">set if you want to update alert with a ticket id</param>
120-
/// <param name="Id">the alert GUID</param>
119+
/// <param name="MonitoringObjectId">SCOM GUID of the monitoring object</param>
120+
/// <param name="IncClosed">if true closed alert is also returned. Default is 'false'</param>
121+
[HttpGet]
122+
[Route("Alerts/MonitoringObject/{MonitoringObjectId:Guid}")]
123+
public IList<MonitoringAlert> GetAlertByMonitoringObjectId(Guid MonitoringObjectId, bool? IncClosed = false)
124+
{
125+
if (MonitoringObjectId == Guid.Empty)
126+
{
127+
throw new HttpResponseException(Request
128+
.CreateResponse(HttpStatusCode.BadRequest));
129+
}
130+
131+
//If include closed alerts
132+
if (IncClosed == true)
133+
{
134+
//Set alert criteria
135+
var Criteria = string.Format("MonitoringObjectId = '{0}'", MonitoringObjectId);
136+
///Get alerts
137+
MonitoringAlertCriteria alertCriteria = new MonitoringAlertCriteria(Criteria);
138+
var Alert = mg.OperationalData.GetMonitoringAlerts(alertCriteria, default(DateTime));
139+
140+
return Alert;
141+
}
142+
143+
else
144+
{
145+
//set alert criteria
146+
var Criteria = string.Format("MonitoringObjectId = '{0}' AND ResolutionState = 0", MonitoringObjectId);
147+
//Get alerts
148+
MonitoringAlertCriteria alertCriteria = new MonitoringAlertCriteria(Criteria);
149+
var Alert = mg.OperationalData.GetMonitoringAlerts(alertCriteria, default(DateTime));
150+
151+
return Alert;
152+
}
153+
}
154+
155+
/// <summary>
156+
/// Updates the specific alert.
157+
/// </summary>
158+
/// <param name="Properties">Json object to update alert properties.
159+
/// All set properties are available.
160+
/// For more information please see technet documentation "http://bit.ly/2zblZLh"</param>
161+
/// <param name="Id">Specify alert guid you want to update</param>
121162
[HttpPut]
122163
[ResponseType(typeof(IEnumerable<MonitoringAlert>))]
123-
[Route("Alerts")]
124-
public IList<MonitoringAlert> UpdateAlertById(Guid Id, byte ResolutionState, string TicketId = "")
164+
[Route("Alerts/{Id:Guid}")]
165+
public IList<MonitoringAlert> UpdateAlertById([FromUri()]Guid Id, [FromBody()] SCOMAlertUpdateModel Properties)
125166
{
126-
if (string.IsNullOrEmpty(ResolutionState.ToString()))
167+
if (Id == Guid.Empty)
127168
{
128169
throw new HttpResponseException(Request
129170
.CreateResponse(HttpStatusCode.BadRequest));
130171
}
131172

173+
// Declare variables
174+
var ResolutionState = Properties.resolutionState;
132175

133176
//alert criteria
134177
var Criteria = string.Format("Id = '{0}'", Id);
135178
MonitoringAlertCriteria alertCriteria = new MonitoringAlertCriteria(Criteria);
136179
var alerts = mg.OperationalData.GetMonitoringAlerts(alertCriteria, default(DateTime));
180+
137181
foreach (MonitoringAlert a in alerts)
138182
{
139183
//If resolution state is set to closed and alert is raised by a monitor. Reset the monitor
140-
if (a.IsMonitorAlert & ResolutionState.ToString() == "255")
184+
if (a.IsMonitorAlert & ResolutionState == "255")
141185
{
142186
//Get object and monitor that raised the alert
143187
Guid monitoringObjectId = a.MonitoringObjectId;
@@ -146,27 +190,59 @@ public IList<MonitoringAlert> UpdateAlertById(Guid Id, byte ResolutionState, str
146190
var monObject = mg.EntityObjects.GetObject<MonitoringObject>(monitoringObjectId, ObjectQueryOptions.Default);
147191
//reset the monitor to 'close' the alert
148192
monObject.ResetMonitoringState(monitor);
149-
193+
150194
}
195+
196+
151197
else
152198
{
153-
154-
if (string.IsNullOrWhiteSpace(TicketId))
199+
200+
if (string.IsNullOrEmpty(ResolutionState))
155201
{
156-
a.ResolutionState = ResolutionState;
157-
string comment = "Changed resolution state (API)";
202+
a.TfsWorkItemId = Properties.tfsWorkItemId;
203+
a.TfsWorkItemOwner = Properties.tfsWorkItemOwner;
204+
a.Owner = Properties.owner;
205+
a.CustomField1 = Properties.customField1;
206+
a.CustomField2 = Properties.customField2;
207+
a.CustomField3 = Properties.customField3;
208+
a.CustomField4 = Properties.customField4;
209+
a.CustomField5 = Properties.customField5;
210+
a.CustomField6 = Properties.customField6;
211+
a.CustomField7 = Properties.customField7;
212+
a.CustomField8 = Properties.customField8;
213+
a.CustomField9 = Properties.customField9;
214+
a.CustomField10 = Properties.customField10;
215+
216+
string comment = "Alert properties updated";
158217
a.Update(comment);
159218

160219
}
161-
//If ticket id is specified.
220+
//If resolution state is specified
162221
else
163222
{
164-
a.ResolutionState = ResolutionState;
165-
a.TicketId = TicketId;
166-
string comment = "Changed resolution state and ticket id (API)";
223+
a.TfsWorkItemId = Properties.tfsWorkItemId;
224+
a.TfsWorkItemOwner = Properties.tfsWorkItemOwner;
225+
a.Owner = Properties.owner;
226+
a.CustomField1 = Properties.customField1;
227+
a.CustomField2 = Properties.customField2;
228+
a.CustomField3 = Properties.customField3;
229+
a.CustomField4 = Properties.customField4;
230+
a.CustomField5 = Properties.customField5;
231+
a.CustomField6 = Properties.customField6;
232+
a.CustomField7 = Properties.customField7;
233+
a.CustomField8 = Properties.customField8;
234+
a.CustomField9 = Properties.customField9;
235+
a.CustomField10 = Properties.customField10;
236+
237+
//Convert string resolution state to byte type
238+
var Res = Convert.ToByte(ResolutionState);
239+
a.ResolutionState = Res;
240+
a.TicketId = Properties.ticketId;
241+
var comments = $"Updated and changed resolution state: {ResolutionState}";
242+
string comment = comments;
167243
a.Update(comment);
168244
}
169-
245+
170246
}
171247

172248
}

SCOM API/Controllers/SCOMObjectController.cs

Lines changed: 73 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@
1414
using System.Collections.ObjectModel;
1515
using SCOM_API.Models;
1616
using System.Configuration;
17+
using System.Web.Http.Description;
1718

1819
namespace SCOM_API.Controllers
1920
{
21+
[RoutePrefix("API/MonitoringObject")]
2022
public class SCOMObjectController : ApiController
2123
{
2224
ManagementGroup mg = null;
@@ -38,7 +40,7 @@ public SCOMObjectController()
3840
/// <response code="400">Bad request check Id</response>
3941
/// <response code="404">Object not found</response>
4042
[HttpGet]
41-
[Route("API/MonitoringObject/{id}")]
43+
[Route("{id}")]
4244
public IHttpActionResult GetMonitoringObject(Guid Id)
4345
{
4446
//Check if guid is not empty
@@ -53,11 +55,11 @@ public IHttpActionResult GetMonitoringObject(Guid Id)
5355

5456
List<SCOMMonitoringObjectModel> MonitoringObject = new List<SCOMMonitoringObjectModel>();
5557

56-
if (monObject !=null)
58+
if (monObject != null)
5759
{
5860
//Get related objects
5961
ReadOnlyCollection<PartialMonitoringObject> RelatedObjects = monObject.GetRelatedPartialMonitoringObjects();
60-
62+
6163
//Add properties
6264
SCOMMonitoringObjectModel mObject = new SCOMMonitoringObjectModel();
6365
mObject.id = monObject.Id;
@@ -86,20 +88,84 @@ public IHttpActionResult GetMonitoringObject(Guid Id)
8688
mObject.relatedObjects = SCOMMonitoringObjectChildObjects;
8789

8890
MonitoringObject.Add(mObject);
89-
91+
9092
//Return object
9193
return Json(MonitoringObject);
9294
}
9395

9496
//If no object found return error code
9597
else
96-
{
97-
98+
{
99+
98100
HttpResponseMessage message = new HttpResponseMessage(HttpStatusCode.NotFound);
99101
message.Content = new StringContent("Monitoring object not found");
100102
throw new HttpResponseException(message);
101103
}
102104
}
103105

106+
/// <summary>
107+
///Gets all monitoring objects of specified class
108+
///Limited properties returned. Use MonitoringObject/Id endpoint for more details
109+
/// </summary>
110+
///<param name="classId">Your class guid</param>
111+
/// <response code="200">OK: returns member of class</response>
112+
/// <response code="204">class found but no objects / no members exist</response>
113+
/// <response code="400">Bad request check classId</response>
114+
/// <response code="404">No such class</response>
115+
116+
[Route("class/{classId}")]
117+
[HttpGet]
118+
[ResponseType(typeof(IEnumerable<SCOMClassObjectModel>))]
119+
public IHttpActionResult GetClassPartialMonitoringObject(Guid classId)
120+
{
121+
122+
if (classId == Guid.Empty)
123+
{
124+
throw new HttpResponseException(Request
125+
.CreateResponse(HttpStatusCode.BadRequest));
126+
}
127+
128+
//Use the input class id to create a criteria for our query
129+
ManagementPackClassCriteria classCriteria = new ManagementPackClassCriteria(string.Format("Id = '{0}'", classId.ToString()));
130+
IList<ManagementPackClass> monitoringClasses = mg.EntityTypes.GetClasses(classCriteria);
131+
132+
133+
List<PartialMonitoringObject> inputClassObjects = new List<PartialMonitoringObject>();
134+
135+
IObjectReader<PartialMonitoringObject> reader = mg.EntityObjects.GetObjectReader<PartialMonitoringObject>(monitoringClasses[0], ObjectQueryOptions.Default);
136+
137+
inputClassObjects.AddRange(reader);
138+
139+
List<SCOMClassObjectModel> classObjects = new List<SCOMClassObjectModel>();
140+
141+
//If objects are found add them to list and return
142+
if (inputClassObjects.Count > 0)
143+
{
144+
145+
foreach (PartialMonitoringObject classObject in inputClassObjects)
146+
{
147+
SCOMClassObjectModel inputClassObject = new SCOMClassObjectModel();
148+
inputClassObject.id = classObject.Id;
149+
inputClassObject.displayName = classObject.DisplayName;
150+
inputClassObject.healthState = classObject.HealthState.ToString();
151+
inputClassObject.path = classObject.Path;
152+
153+
classObjects.Add(inputClassObject);
154+
}
155+
156+
return Json(classObjects);
157+
}
158+
159+
//if class does not have any monitoring objects return 'no content'
160+
else
161+
{
162+
HttpResponseMessage message = new HttpResponseMessage(HttpStatusCode.NoContent);
163+
message.Content = new StringContent("Class found but no object exist");
164+
throw new HttpResponseException(message);
165+
}
166+
167+
}
104168
}
105-
}//END
169+
170+
}
171+
//END

0 commit comments

Comments
 (0)