From 04d6b5fdfd05e1c794d6be6608c05ade77726b37 Mon Sep 17 00:00:00 2001 From: Michael James Hoppal Date: Wed, 15 Jun 2016 13:22:18 -0600 Subject: [PATCH] Add patch to notification method and clean up code Update docs with new command Move validation of the period field to the setter for java api which is called by jackson as it constructs the command objects. Add tempest tests for patching Change-Id: I7f31aa059601c0390c42b0f5bdf4091706f6660d --- docs/monasca-api-spec.md | 71 +++++++ .../java/monasca/api/MonApiApplication.java | 1 + .../CreateNotificationMethodCommand.java | 21 +- .../PatchNotificationMethodCommand.java | 99 +++++++++ .../UpdateNotificationMethodCommand.java | 18 +- .../NotificationMethodValidation.java | 11 +- .../resource/NotificationMethodResource.java | 37 +++- .../NotificationMethodResourceTest.java | 14 -- monasca_api/api/notifications_api_v2.py | 3 + monasca_api/v2/reference/notifications.py | 24 +++ .../services/monasca_client.py | 19 ++ .../tests/api/test_notification_methods.py | 189 ++++++++++++++++++ 12 files changed, 479 insertions(+), 28 deletions(-) create mode 100644 java/src/main/java/monasca/api/app/command/PatchNotificationMethodCommand.java diff --git a/docs/monasca-api-spec.md b/docs/monasca-api-spec.md index 4115f9fd0..9d770a8d2 100644 --- a/docs/monasca-api-spec.md +++ b/docs/monasca-api-spec.md @@ -1707,6 +1707,77 @@ Returns a JSON notification method object with the following fields: ```` ___ +## Patch Notification Method +Patch the specified notification method. + +### PATCH /v2.0/notification-methods/{notification_method_id} + +#### Headers +* X-Auth-Token (string, required) - Keystone auth token +* Content-Type (string, required) - application/json +* Accept (string) - application/json + +#### Path Parameters +* notification_method_id (string, required) - ID of the notification method to update. + +#### Query Parameters +None. + +#### Request Body +* name (string(250), optional) - A descriptive name of the notifcation method. +* type (string(100), optional) - The type of notification method (`EMAIL`, `WEBHOOK`, or `PAGERDUTY` ). +* address (string(100), optional) - The email/url address to notify. +* period (integer, optional) - The interval in seconds to periodically send the notification. Only can be set as a non zero value for WEBHOOK methods. Allowed periods for Webhooks by default are 0, 60. You can change allow periods for webhooks in the api config. The notification will continue to be sent at the defined interval until the alarm it is associated with changes state. + +#### Request Examples +```` +PATCH /v2.0/notification-methods/35cc6f1c-3a29-49fb-a6fc-d9d97d190508 HTTP/1.1 +Host: 192.168.10.4:8080 +Content-Type: application/json +X-Auth-Token: 2b8882ba2ec44295bf300aecb2caa4f7 +Cache-Control: no-cache + +{ + "name":"New name of notification method", + "type":"EMAIL", + "address":"jane.doe@hp.com", + "period":0 +} +```` + +### Response + +#### Status Code +* 200 - OK + +#### Response Body +Returns a JSON notification method object with the following fields: + +* id (string) - ID of notification method +* links ([link]) +* name (string) - Name of notification method +* type (string) - Type of notification method +* address (string) - Address of notification method +* period (integer) - Period of notification method + +#### Response Examples +```` +{ + "id":"35cc6f1c-3a29-49fb-a6fc-d9d97d190508", + "links":[ + { + "rel":"self", + "href":"http://192.168.10.4:8080/v2.0/notification-methods/35cc6f1c-3a29-49fb-a6fc-d9d97d190508" + } + ], + "name":"New name of notification method", + "type":"EMAIL", + "address":"jane.doe@hp.com", + "period":0 +} +```` +___ + ## Delete Notification Method Delete the specified notification method. diff --git a/java/src/main/java/monasca/api/MonApiApplication.java b/java/src/main/java/monasca/api/MonApiApplication.java index d064050a0..89a008f54 100644 --- a/java/src/main/java/monasca/api/MonApiApplication.java +++ b/java/src/main/java/monasca/api/MonApiApplication.java @@ -129,6 +129,7 @@ public class MonApiApplication extends Application { PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES); environment.getObjectMapper().enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY); environment.getObjectMapper().disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + environment.getObjectMapper().disable(DeserializationFeature.WRAP_EXCEPTIONS); SimpleModule module = new SimpleModule("SerializationModule"); module.addSerializer(new SubAlarmExpressionSerializer()); environment.getObjectMapper().registerModule(module); diff --git a/java/src/main/java/monasca/api/app/command/CreateNotificationMethodCommand.java b/java/src/main/java/monasca/api/app/command/CreateNotificationMethodCommand.java index cb4bbac6a..40da72538 100644 --- a/java/src/main/java/monasca/api/app/command/CreateNotificationMethodCommand.java +++ b/java/src/main/java/monasca/api/app/command/CreateNotificationMethodCommand.java @@ -13,13 +13,16 @@ */ package monasca.api.app.command; + import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; + import org.hibernate.validator.constraints.NotEmpty; import java.util.List; import monasca.api.app.validation.NotificationMethodValidation; +import monasca.api.app.validation.Validation; import monasca.api.domain.model.notificationmethod.NotificationMethodType; public class CreateNotificationMethodCommand { @@ -32,6 +35,7 @@ public class CreateNotificationMethodCommand { @Size(min = 1, max = 512) public String address; public String period; + private int convertedPeriod = 0; public CreateNotificationMethodCommand() {this.period = "0";} @@ -39,7 +43,8 @@ public class CreateNotificationMethodCommand { this.name = name; this.type = type; this.address = address; - this.period = period == null ? "0" : period; + period = period == null ? "0" : period; + this.setPeriod(period); } @Override @@ -68,11 +73,22 @@ public class CreateNotificationMethodCommand { return false; if (type != other.type) return false; + if (convertedPeriod != other.convertedPeriod) + return false; return true; } public void validate(List validPeriods) { - NotificationMethodValidation.validate(type, address, period, validPeriods); + NotificationMethodValidation.validate(type, address, convertedPeriod, validPeriods); + } + + public void setPeriod(String period){ + this.period = period; + this.convertedPeriod = Validation.parseAndValidateNumber(period, "period"); + } + + public int getConvertedPeriod(){ + return this.convertedPeriod; } @Override @@ -83,6 +99,7 @@ public class CreateNotificationMethodCommand { result = prime * result + ((type == null) ? 0 : type.hashCode()); result = prime * result + ((address == null) ? 0 : address.hashCode()); result = prime * result + ((period == null) ? 0 : period.hashCode()); + result = prime * result + convertedPeriod; return result; } } diff --git a/java/src/main/java/monasca/api/app/command/PatchNotificationMethodCommand.java b/java/src/main/java/monasca/api/app/command/PatchNotificationMethodCommand.java new file mode 100644 index 000000000..36aae7e27 --- /dev/null +++ b/java/src/main/java/monasca/api/app/command/PatchNotificationMethodCommand.java @@ -0,0 +1,99 @@ +/* + * (C) Copyright 2016 Hewlett Packard Enterprise Development Company LP + * + * 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 monasca.api.app.command; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.List; + +import javax.validation.constraints.Size; + +import monasca.api.app.validation.NotificationMethodValidation; +import monasca.api.app.validation.Validation; +import monasca.api.domain.model.notificationmethod.NotificationMethodType; + +public class PatchNotificationMethodCommand { + @Size(min = 1, max = 250) + public String name; + public NotificationMethodType type; + @Size(min = 1, max = 512) + public String address; + public String period; + private int convertedPeriod = 0; + + public PatchNotificationMethodCommand() {} + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + PatchNotificationMethodCommand other = (PatchNotificationMethodCommand) obj; + if (address == null) { + if (other.address != null) + return false; + } else if (!address.equals(other.address)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (period == null) { + if (other.period != null) + return false; + } else if (!period.equals(other.period)) + return false; + if (type != other.type) + return false; + if (convertedPeriod != other.convertedPeriod) + return false; + return true; + } + + public void validate(List validPeriods) { + NotificationMethodValidation.validate(type, address, convertedPeriod, validPeriods); + } + + @JsonProperty("period") + public void setPeriod(String period){ + this.period = period; + this.convertedPeriod = Validation.parseAndValidateNumber(period, "period"); + } + + @JsonIgnore + public void setPeriod(int period){ + this.convertedPeriod = period; + } + + public int getConvertedPeriod(){ + return this.convertedPeriod; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((type == null) ? 0 : type.hashCode()); + result = prime * result + ((address == null) ? 0 : address.hashCode()); + result = prime * result + ((period == null) ? 0 : period.hashCode()); + result = prime * result + convertedPeriod; + return result; + } +} diff --git a/java/src/main/java/monasca/api/app/command/UpdateNotificationMethodCommand.java b/java/src/main/java/monasca/api/app/command/UpdateNotificationMethodCommand.java index ec7eb3239..91cfbced7 100644 --- a/java/src/main/java/monasca/api/app/command/UpdateNotificationMethodCommand.java +++ b/java/src/main/java/monasca/api/app/command/UpdateNotificationMethodCommand.java @@ -20,6 +20,7 @@ import org.hibernate.validator.constraints.NotEmpty; import java.util.List; import monasca.api.app.validation.NotificationMethodValidation; +import monasca.api.app.validation.Validation; import monasca.api.domain.model.notificationmethod.NotificationMethodType; public class UpdateNotificationMethodCommand { @@ -33,6 +34,7 @@ public class UpdateNotificationMethodCommand { public String address; @NotNull public String period; + private int convertedPeriod = 0; public UpdateNotificationMethodCommand() {} @@ -40,7 +42,7 @@ public class UpdateNotificationMethodCommand { this.name = name; this.type = type; this.address = address; - this.period = period; + this.setPeriod(period); } @Override @@ -69,11 +71,22 @@ public class UpdateNotificationMethodCommand { return false; if (type != other.type) return false; + if (convertedPeriod != other.convertedPeriod) + return false; return true; } public void validate(List validPeriods) { - NotificationMethodValidation.validate(type, address, period, validPeriods); + NotificationMethodValidation.validate(type, address, convertedPeriod, validPeriods); + } + + public void setPeriod(String period){ + this.period = period; + this.convertedPeriod = Validation.parseAndValidateNumber(period, "period"); + } + + public int getConvertedPeriod(){ + return this.convertedPeriod; } @Override @@ -84,6 +97,7 @@ public class UpdateNotificationMethodCommand { result = prime * result + ((type == null) ? 0 : type.hashCode()); result = prime * result + ((address == null) ? 0 : address.hashCode()); result = prime * result + ((period == null) ? 0 : period.hashCode()); + result = prime * result + convertedPeriod; return result; } } diff --git a/java/src/main/java/monasca/api/app/validation/NotificationMethodValidation.java b/java/src/main/java/monasca/api/app/validation/NotificationMethodValidation.java index e912fff9a..05432ff68 100644 --- a/java/src/main/java/monasca/api/app/validation/NotificationMethodValidation.java +++ b/java/src/main/java/monasca/api/app/validation/NotificationMethodValidation.java @@ -31,14 +31,13 @@ public class NotificationMethodValidation { TEST_TLD_VALIDATOR, UrlValidator.ALLOW_LOCAL_URLS | UrlValidator.ALLOW_2_SLASHES); - public static void validate(NotificationMethodType type, String address, String period, + public static void validate(NotificationMethodType type, String address, int period, List validPeriods) { - int convertedPeriod = Validation.parseAndValidateNumber(period, "period"); switch (type) { case EMAIL : { if (!EmailValidator.getInstance(true).isValid(address)) throw Exceptions.unprocessableEntity("Address %s is not of correct format", address); - if (convertedPeriod != 0) + if (period != 0) throw Exceptions.unprocessableEntity("Period can not be non zero for Email"); } break; case WEBHOOK : { @@ -46,12 +45,12 @@ public class NotificationMethodValidation { throw Exceptions.unprocessableEntity("Address %s is not of correct format", address); } break; case PAGERDUTY : { - if (convertedPeriod != 0) + if (period != 0) throw Exceptions.unprocessableEntity("Period can not be non zero for Pagerduty"); } break; } - if (convertedPeriod != 0 && !validPeriods.contains(convertedPeriod)){ - throw Exceptions.unprocessableEntity("%d is not a valid period", convertedPeriod); + if (period != 0 && !validPeriods.contains(period)){ + throw Exceptions.unprocessableEntity("%d is not a valid period", period); } } } diff --git a/java/src/main/java/monasca/api/resource/NotificationMethodResource.java b/java/src/main/java/monasca/api/resource/NotificationMethodResource.java index 7bde467e5..8233af36a 100644 --- a/java/src/main/java/monasca/api/resource/NotificationMethodResource.java +++ b/java/src/main/java/monasca/api/resource/NotificationMethodResource.java @@ -39,11 +39,15 @@ import javax.ws.rs.core.UriInfo; import monasca.api.ApiConfig; import monasca.api.app.command.CreateNotificationMethodCommand; +import monasca.api.app.command.PatchNotificationMethodCommand; import monasca.api.app.command.UpdateNotificationMethodCommand; +import monasca.api.app.validation.NotificationMethodValidation; import monasca.api.app.validation.Validation; import monasca.api.domain.model.notificationmethod.NotificationMethod; import monasca.api.domain.model.notificationmethod.NotificationMethodRepo; +import monasca.api.domain.model.notificationmethod.NotificationMethodType; import monasca.api.infrastructure.persistence.PersistUtils; +import monasca.api.resource.annotation.PATCH; /** * Notification Method resource implementation. @@ -74,11 +78,10 @@ public class NotificationMethodResource { public Response create(@Context UriInfo uriInfo, @HeaderParam("X-Tenant-Id") String tenantId, @Valid CreateNotificationMethodCommand command) { command.validate(this.validPeriods); - int period = Validation.parseAndValidateNumber(command.period, "period"); NotificationMethod notificationMethod = Links.hydrate(repo.create(tenantId, command.name, command.type, - command.address, period), uriInfo, + command.address, command.getConvertedPeriod()), uriInfo, false); return Response.created(URI.create(notificationMethod.getId())).entity(notificationMethod) .build(); @@ -123,14 +126,40 @@ public class NotificationMethodResource { @PathParam("notification_method_id") String notificationMethodId, @Valid UpdateNotificationMethodCommand command) { command.validate(this.validPeriods); - int period = Validation.parseAndValidateNumber(command.period, "period"); return Links.hydrate( repo.update(tenantId, notificationMethodId, command.name, command.type, - command.address, period), + command.address, command.getConvertedPeriod()), uriInfo, true); } + @PATCH + @Timed + @Path("/{notification_method_id}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public NotificationMethod patch(@Context UriInfo uriInfo, + @HeaderParam("X-Tenant-Id") String tenantId, + @PathParam("notification_method_id") String notificationMethodId, + @Valid PatchNotificationMethodCommand command) { + NotificationMethod originalNotificationMethod = repo.findById(tenantId, notificationMethodId); + String name = command.name == null ? originalNotificationMethod.getName() + : command.name; + NotificationMethodType type = command.type == null ? originalNotificationMethod.getType() + : command.type; + String address = command.address == null ? originalNotificationMethod.getAddress() + : command.address; + int period = command.period == null ? originalNotificationMethod.getPeriod() + : command.getConvertedPeriod(); + + NotificationMethodValidation.validate(type, address, period, this.validPeriods); + + return Links.hydrate( + repo.update(tenantId, notificationMethodId, name, type, + address, period), + uriInfo, true); + } + @DELETE @Timed @Path("/{notification_method_id}") diff --git a/java/src/test/java/monasca/api/resource/NotificationMethodResourceTest.java b/java/src/test/java/monasca/api/resource/NotificationMethodResourceTest.java index 1030eeecf..c496a5a3d 100644 --- a/java/src/test/java/monasca/api/resource/NotificationMethodResourceTest.java +++ b/java/src/test/java/monasca/api/resource/NotificationMethodResourceTest.java @@ -208,20 +208,6 @@ public class NotificationMethodResourceTest extends AbstractMonApiResourceTest { "[address size must be between 1 and 512"); } - public void should422OnNonIntPeriod() { - ClientResponse response = - client() - .resource("/v2.0/notification-methods") - .header("X-Tenant-Id", "abc") - .header("Content-Type", MediaType.APPLICATION_JSON) - .post(ClientResponse.class, - new CreateNotificationMethodCommand("MyEmail", NotificationMethodType.EMAIL, "a@a.com", "not a int")); - - String e = response.getEntity(String.class); - ErrorMessages.assertThat(e).matches("unprocessable_entity", 422, - "period (not a int) must be valid number"); - } - public void should422OnNonZeroPeriodForEmail() { ClientResponse response = client() diff --git a/monasca_api/api/notifications_api_v2.py b/monasca_api/api/notifications_api_v2.py index 7c8abb0d1..1081d88c6 100644 --- a/monasca_api/api/notifications_api_v2.py +++ b/monasca_api/api/notifications_api_v2.py @@ -33,3 +33,6 @@ class NotificationsV2API(object): def on_put(self, req, res, notification_method_id): res.status = '501 Not Implemented' + + def on_patch(self, req, res, notification_method_id): + res.status = '501 Not Implemented' diff --git a/monasca_api/v2/reference/notifications.py b/monasca_api/v2/reference/notifications.py index 3b8ff35b2..99150b2a8 100644 --- a/monasca_api/v2/reference/notifications.py +++ b/monasca_api/v2/reference/notifications.py @@ -169,6 +169,18 @@ class Notifications(notifications_api_v2.NotificationsV2API): self._notifications_repo.delete_notification(tenant_id, notification_id) + @resource.resource_try_catch_block + def _patch_get_notification(self, tenant_id, notification_id, notification): + original_notification = self._notifications_repo.list_notification(tenant_id, notification_id) + if 'name' not in notification: + notification['name'] = original_notification['name'] + if 'type' not in notification: + notification['type'] = original_notification['type'] + if 'address' not in notification: + notification['address'] = original_notification['address'] + if 'period' not in notification: + notification['period'] = original_notification['period'] + def on_post(self, req, res): helpers.validate_json_content_type(req) helpers.validate_authorization(req, self._default_authorized_roles) @@ -225,3 +237,15 @@ class Notifications(notifications_api_v2.NotificationsV2API): notification, req.uri) res.body = helpers.dumpit_utf8(result) res.status = falcon.HTTP_200 + + def on_patch(self, req, res, notification_method_id): + helpers.validate_json_content_type(req) + helpers.validate_authorization(req, self._default_authorized_roles) + notification = helpers.read_http_resource(req) + tenant_id = helpers.get_tenant_id(req) + self._patch_get_notification(tenant_id, notification_method_id, notification) + self._parse_and_validate_notification(notification, require_all=True) + result = self._update_notification(notification_method_id, tenant_id, + notification, req.uri) + res.body = helpers.dumpit_utf8(result) + res.status = falcon.HTTP_200 diff --git a/monasca_tempest_tests/services/monasca_client.py b/monasca_tempest_tests/services/monasca_client.py index 12810512f..3f0ee18ff 100644 --- a/monasca_tempest_tests/services/monasca_client.py +++ b/monasca_tempest_tests/services/monasca_client.py @@ -126,6 +126,25 @@ class MonascaClient(rest_client.RestClient): resp, response_body = self.put(uri, json.dumps(request_body)) return resp, json.loads(response_body) + def patch_notification_method(self, + id, + name=None, + type=None, + address=None, + period=None): + uri = 'notification-methods/' + id + request_body = {} + if name is not None: + request_body['name'] = name + if type is not None: + request_body['type'] = type + if address is not None: + request_body['address'] = address + if period is not None: + request_body['period'] = period + resp, response_body = self.patch(uri, json.dumps(request_body)) + return resp, json.loads(response_body) + def create_alarm_definitions(self, alarm_definitions): uri = 'alarm-definitions' request_body = json.dumps(alarm_definitions) diff --git a/monasca_tempest_tests/tests/api/test_notification_methods.py b/monasca_tempest_tests/tests/api/test_notification_methods.py index 72bef3664..0092d561a 100644 --- a/monasca_tempest_tests/tests/api/test_notification_methods.py +++ b/monasca_tempest_tests/tests/api/test_notification_methods.py @@ -658,3 +658,192 @@ class TestNotificationMethods(base.BaseMonascaTest): resp, response_body = \ self.monasca_client.delete_notification_method(id) self.assertEqual(204, resp.status) + + @test.attr(type="gate") + def test_patch_notification_method_name(self): + name = data_utils.rand_name('notification-') + notification = helpers.create_notification(name=name) + resp, response_body = self.monasca_client.create_notifications( + notification) + self.assertEqual(201, resp.status) + self.assertEqual(name, response_body['name']) + id = response_body['id'] + new_name = name + 'update' + resp, response_body = self.monasca_client.\ + patch_notification_method(id, new_name) + self.assertEqual(200, resp.status) + self.assertEqual(new_name, response_body['name']) + resp, response_body = self.monasca_client.\ + delete_notification_method(id) + self.assertEqual(204, resp.status) + + @test.attr(type="gate") + def test_patch_notification_method_type(self): + type = 'EMAIL' + notification = helpers.create_notification(type=type) + resp, response_body = self.monasca_client.create_notifications( + notification) + self.assertEqual(201, resp.status) + self.assertEqual(type, response_body['type']) + id = response_body['id'] + new_type = 'PAGERDUTY' + resp, response_body = \ + self.monasca_client.\ + patch_notification_method(id, type=new_type) + self.assertEqual(200, resp.status) + self.assertEqual(new_type, response_body['type']) + resp, response_body = self.monasca_client.\ + delete_notification_method(id) + self.assertEqual(204, resp.status) + + @test.attr(type="gate") + def test_patch_notification_method_address(self): + address = DEFAULT_EMAIL_ADDRESS + notification = helpers.create_notification(address=address) + resp, response_body = self.monasca_client.create_notifications( + notification) + self.assertEqual(201, resp.status) + self.assertEqual(address, response_body['address']) + id = response_body['id'] + new_address = 'jane.doe@domain.com' + resp, response_body = self.monasca_client.\ + patch_notification_method(id, address=new_address) + self.assertEqual(200, resp.status) + self.assertEqual(new_address, response_body['address']) + resp, response_body = \ + self.monasca_client.delete_notification_method(id) + self.assertEqual(204, resp.status) + + @test.attr(type="gate") + @test.attr(type=['negative']) + def test_patch_notification_method_name_exceeds_max_length(self): + name = data_utils.rand_name('notification-') + notification = helpers.create_notification(name=name) + resp, response_body = self.monasca_client.create_notifications( + notification) + id = response_body['id'] + self.assertEqual(201, resp.status) + new_name_long = "x" * (constants.MAX_NOTIFICATION_METHOD_NAME_LENGTH + + 1) + self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), + self.monasca_client.patch_notification_method, id, + name=new_name_long) + resp, response_body = \ + self.monasca_client.delete_notification_method(id) + self.assertEqual(204, resp.status) + + @test.attr(type="gate") + @test.attr(type=['negative']) + def test_patch_notification_method_invalid_type(self): + name = data_utils.rand_name('notification-') + notification = helpers.create_notification(name=name) + resp, response_body = self.monasca_client.create_notifications( + notification) + id = response_body['id'] + self.assertEqual(201, resp.status) + self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), + self.monasca_client.patch_notification_method, id, type='random') + resp, response_body = \ + self.monasca_client.delete_notification_method(id) + self.assertEqual(204, resp.status) + + @test.attr(type="gate") + @test.attr(type=['negative']) + def test_patch_notification_method_address_exceeds_max_length(self): + name = data_utils.rand_name('notification-') + notification = helpers.create_notification(name=name) + resp, response_body = self.monasca_client.create_notifications( + notification) + id = response_body['id'] + self.assertEqual(201, resp.status) + new_address_long = "x" * ( + constants.MAX_NOTIFICATION_METHOD_ADDRESS_LENGTH + 1) + self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), + self.monasca_client.patch_notification_method, id, address=new_address_long) + resp, response_body = \ + self.monasca_client.delete_notification_method(id) + self.assertEqual(204, resp.status) + + @test.attr(type="gate") + @test.attr(type=['negative']) + def test_patch_email_notification_method_with_nonzero_period(self): + name = data_utils.rand_name('notification-') + notification = helpers.create_notification(name=name) + resp, response_body = self.monasca_client.create_notifications( + notification) + id = response_body['id'] + self.assertEqual(201, resp.status) + self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), + self.monasca_client.patch_notification_method, id, period=60) + resp, response_body = \ + self.monasca_client.delete_notification_method(id) + self.assertEqual(204, resp.status) + + @test.attr(type="gate") + @test.attr(type=['negative']) + def test_patch_webhook_notification_method_to_email_with_nonzero_period(self): + name = data_utils.rand_name('notification-') + notification = helpers.create_notification(name=name, + type='WEBHOOK', + address='http://localhost/test01', + period=60) + resp, response_body = self.monasca_client.create_notifications( + notification) + id = response_body['id'] + self.assertEqual(201, resp.status) + self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), + self.monasca_client.patch_notification_method, id, type='EMAIL') + resp, response_body = \ + self.monasca_client.delete_notification_method(id) + self.assertEqual(204, resp.status) + + @test.attr(type="gate") + @test.attr(type=['negative']) + def test_patch_webhook_notification_method_to_pagerduty_with_nonzero_period(self): + name = data_utils.rand_name('notification-') + notification = helpers.create_notification(name=name, + type='WEBHOOK', + address='http://localhost/test01', + period=60) + resp, response_body = self.monasca_client.create_notifications( + notification) + id = response_body['id'] + self.assertEqual(201, resp.status) + self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), + self.monasca_client.patch_notification_method, id, type='PAGERDUTY') + resp, response_body = \ + self.monasca_client.delete_notification_method(id) + self.assertEqual(204, resp.status) + + @test.attr(type="gate") + @test.attr(type=['negative']) + def test_patch_notification_method_with_non_int_period(self): + name = data_utils.rand_name('notification-') + notification = helpers.create_notification(name=name) + resp, response_body = self.monasca_client.create_notifications( + notification) + id = response_body['id'] + self.assertEqual(201, resp.status) + self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), + self.monasca_client.patch_notification_method, id, period='zero') + resp, response_body = \ + self.monasca_client.delete_notification_method(id) + self.assertEqual(204, resp.status) + + @test.attr(type="gate") + @test.attr(type=['negative']) + def test_patch_webhook_notification_method_with_invalid_period(self): + name = data_utils.rand_name('notification-') + notification = helpers.create_notification(name=name, + type='WEBHOOK', + address='http://localhost/test01', + period=60) + resp, response_body = self.monasca_client.create_notifications( + notification) + id = response_body['id'] + self.assertEqual(201, resp.status) + self.assertRaises((exceptions.BadRequest, exceptions.UnprocessableEntity), + self.monasca_client.patch_notification_method, id, period=5) + resp, response_body = \ + self.monasca_client.delete_notification_method(id) + self.assertEqual(204, resp.status)