When service is not available, JAX-RS service returns 404 and not 500 why?When service is not available, JAX-RS service returns 404 and not 500 why?https://liferay.dev/en/c/message_boards/find_thread?p_l_id=119785333&threadId=1195191432024-03-29T02:35:16Z2024-03-29T02:35:16ZRE: When service is not available, JAX-RS service returns 404 and not 500 wChristoph Rabelhttps://liferay.dev/en/c/message_boards/find_message?p_l_id=119785333&messageId=1195575072020-07-07T19:06:02Z2020-07-07T19:06:02ZSorry, my bad, I misunderstood. The above code is an alternative to the extension select. When you wrote:<br />"Ok I found it. I don't see the jaxb-json extension as shown below. "<br />I thought that you found the issue (and you were just talking about the jaxrs:check output) and that the extension was not attached when you had the problem.I am not sure what the XMLRootElement annotation does/requires (I know in general, but not in this context). I don't think that it matters, I think that it has to do something with the extension.select annotation and that jaxb-json cannot be attached in some cases.Christoph Rabel2020-07-07T19:06:02ZRE: When service is not available, JAX-RS service returns 404 and not 500 wKevin Matthewshttps://liferay.dev/en/c/message_boards/find_message?p_l_id=119785333&messageId=1195570422020-07-07T18:35:09Z2020-07-07T18:35:09ZOk I will try and remove (XMLRootElement) annotation and see what happens. But I thought the whole purpose of using jaxb was marshall/unmarshall pojo to json and vice versa and this element was needed. When i did the jaxrs-check gogo it did not show any missing requirements and showed the jaxb extension attached. I am just concern why sometimes I get 404 when the service is active. I will watch for a 404 error and if i get it , will run the jaxrs-check command to see what happens. <div class="quote-title">Christoph Rabel:</div><blockquote><br />You can try to remove it, I guess, you will get a 415 Unsuspected media type error then. But I could be wrong here, you could try.<br />When we started with the rest services, I didn't know that we could just add an extension select for jaxb-json. So we add the provider directly to the singleton to make it available. e.g. like this:<br /> Set<Object> singletons = new HashSet<>();<br /> JacksonJsonProvider provider = new JacksonJsonProvider();<br /> ObjectMapper mapper = new ObjectMapper();<br /> mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);<br /> provider.setMapper(mapper);<br /> singletons.add(provider);<br />This works flawless for us, with 7.1, 7.2, 7.3. We never used the extension.select method simply because it simply was not important to me.</blockquote>Kevin Matthews2020-07-07T18:35:09ZRE: When service is not available, JAX-RS service returns 404 and not 500 wChristoph Rabelhttps://liferay.dev/en/c/message_boards/find_message?p_l_id=119785333&messageId=1195551442020-07-07T18:23:24Z2020-07-07T18:23:24ZYou can try to remove it, I guess, you will get a 415 Unsuspected media type error then. But I could be wrong here, you could try.<br />When we started with the rest services, I didn't know that we could just add an extension select for jaxb-json. So we add the provider directly to the singleton to make it available. e.g. like this:<br /> Set<Object> singletons = new HashSet<>();<br /> JacksonJsonProvider provider = new JacksonJsonProvider();<br /> ObjectMapper mapper = new ObjectMapper();<br /> mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);<br /> provider.setMapper(mapper);<br /> singletons.add(provider);<br />This works flawless for us, with 7.1, 7.2, 7.3. We never used the extension.select method simply because it simply was not important to me.Christoph Rabel2020-07-07T18:23:24ZRE: When service is not available, JAX-RS service returns 404 and not 500 wKevin Matthewshttps://liferay.dev/en/c/message_boards/find_message?p_l_id=119785333&messageId=1195566942020-07-07T18:02:08Z2020-07-07T18:02:08ZOk I found it. I don't see the jaxb-json extension as shown below. Is this needed if we use <em>@XmlRootElement annotation on our pojos's</em>? Was this something you programmatically defined in you DS component?<br /><br />Application Portal-Api.Rest (11278) /portal-api POST /ArtifactService Consumes: [application/json] Produces: [application/js on]<br /> GET / Consumes: null Produces: [text/plain]<br /> DELETE /ArtifactService/{id} Consumes: null Produces: [application/json]<br /> GET /artifact/users Consumes: null Produces: [text/plain]<br /> GET /artifact/Scheduler/{hostname} Consumes: null Produces: [application/json]<br /> POST /ArtifactService/{tppid} Consumes: null Produces: null<br /> POST /ArtifactMerchantService Consumes: [application/json] Produces: [application/json]<br /> GET /artifact/MerchantNotification Consumes: null Produces: [application/json] <br /> Attached extensions:<br /> jaxb-json (1338)<br /> Liferay.OAuth2 (2851)<br /> Liferay.Access.Control (1320)Kevin Matthews2020-07-07T18:02:08ZRE: When service is not available, JAX-RS service returns 404 and not 500 wChristoph Rabelhttps://liferay.dev/en/c/message_boards/find_message?p_l_id=119785333&messageId=1195547832020-07-07T17:50:49Z2020-07-07T17:50:49Z<html><head></head><body>That message isn't relevant. You should something like that for your application:<br><pre><code>Application .default (4692) /rest
Attached extensions:
jaxb-json (974)
Liferay.OAuth2.HTTP.method.request.checker (647)
Liferay.Access.Control (969)
Liferay.OAuth2 (2783)</code></pre>Not exactly that, I think OAuth2 shouldn't attach, just giving an example.</body></html>Christoph Rabel2020-07-07T17:50:49ZRE: When service is not available, JAX-RS service returns 404 and not 500 wKevin Matthewshttps://liferay.dev/en/c/message_boards/find_message?p_l_id=119785333&messageId=1195563462020-07-07T17:44:35Z2020-07-07T17:44:35ZI did a jaxrs:check and got the followig below:<br /><strong>Extensions report:<br /> Extension Liferay.OAuth2.annotations.feature (1792) is waiting for an application: (|(oauth2.scope.checker.type=annotations)(oauth2.scopechecker.type=annotations))</strong><br />This my DS component setup as I have oauth2 turned of by issue this property oauth2.scopechecker.type=none<br /><br /><strong>@Component(property = { JaxrsWhiteboardConstants.JAX_RS_APPLICATION_BASE + "=/portal-api",<br /> JaxrsWhiteboardConstants.JAX_RS_NAME + "=Portal-Api.Rest", <br /> "oauth2.scopechecker.type=none",<br /> "auth.verifier.guest.allowed=true", <br /> //"liferay.access.control.disable=true", <br /> "osgi.jaxrs.extension.select=(osgi.jaxrs.name=jaxb-json)"<br /> // "osgi.jaxrs.extension.select=(component.name=your.user.context.provider.extension)"<br />}, service = Application.class)</strong><br /><div class="quote-title">Christoph Rabel:</div><blockquote><br />We use a monitoring tool called Zabbix to monitor the servers and check the services from there regularly. And we check the services when we automatically deploy to make sure they are up and running.<br />---<br />Since the bundle is started, it probably is something that happens afterwards that causes problems. I had that before with missing extensions. We have ContextProviders here for User, Company and Locale and we select them using osgi properties. But when they are missing/not deployed, the bundle deploys just fine and don't work. In that case only jaxrs:check gives any hint what's wrong. The message from jaxrs:check was fixed, it could be that there is just a single line at the end in your version telling you something like "123 is missing 345".</blockquote>Kevin Matthews2020-07-07T17:44:35ZRE: When service is not available, JAX-RS service returns 404 and not 500 wChristoph Rabelhttps://liferay.dev/en/c/message_boards/find_message?p_l_id=119785333&messageId=1195544362020-07-07T17:26:54Z2020-07-07T17:26:54ZWe use a monitoring tool called Zabbix to monitor the servers and check the services from there regularly. And we check the services when we automatically deploy to make sure they are up and running.<br />---<br />Since the bundle is started, it probably is something that happens afterwards that causes problems. I had that before with missing extensions. We have ContextProviders here for User, Company and Locale and we select them using osgi properties. But when they are missing/not deployed, the bundle deploys just fine and don't work. In that case only jaxrs:check gives any hint what's wrong. The message from jaxrs:check was fixed, it could be that there is just a single line at the end in your version telling you something like "123 is missing 345".Christoph Rabel2020-07-07T17:26:54ZRE: When service is not available, JAX-RS service returns 404 and not 500 wKevin Matthewshttps://liferay.dev/en/c/message_boards/find_message?p_l_id=119785333&messageId=1195559952020-07-07T16:56:33Z2020-07-07T16:56:33Z<div class="quote-title">Christoph Rabel:</div><blockquote><br />Yes, I understand. But Liferay is not incorrect in returning a 404 errorcode because it is the common return type for urls that do not exist. In any case, it won't be changed for 7.2 and even for 7.3. And since it could break existing applications relying on that error code, it probably will never be changed.<br />I can't say that I have seen any issues, redeploying our rest services seems to work pretty fine. But we are on DXP with Tomcat, so it could be different there. <strong>We are using 7.2 GA2 CE edition</strong><br /></blockquote><blockquote>Have you tried to use jaxrs:check in the gogo shell when the service fails? <strong>I haven't try that command. I will thanks for the recommendation. Also, I like your idea of doing a health check. I will create a separate bundle to check for services as you mention to return a 200. Did you create a separate OSGI bundle for your health check or was it an outside service non OSGI service checking connectivity?</strong><br /></blockquote><blockquote>Maybe it is waiting for an extension, jaxb-json maybe? Could possbile be but how would I know? <strong>However, as far as service not available, I did uninstall some bundle fragments that I used in previous version of Liferay 7.0 that was running in INSTALLED state in new LR 7.2 instance, that could be a culprit not sure <img alt="emoticon" src="@theme_images_path@/emoticons/happy.gif" >. I have modified those bundles rebuild the code in 7.2 and ensured it went into RESOLVED state for these web fragments. Not sure if when bundles are in INSTALLED state would impact JAX-RS bundles even if they uses the same export packages. </strong></blockquote>Kevin Matthews2020-07-07T16:56:33ZRE: When service is not available, JAX-RS service returns 404 and not 500 wChristoph Rabelhttps://liferay.dev/en/c/message_boards/find_message?p_l_id=119785333&messageId=1195537272020-07-07T16:22:37Z2020-07-07T16:22:37ZYes, I understand. But Liferay is not incorrect in returning a 404 errorcode because it is the common return type for urls that do not exist. In any case, it won't be changed for 7.2 and even for 7.3. And since it could break existing applications relying on that error code, it probably will never be changed.<br />I can't say that I have seen any issues, redeploying our rest services seems to work pretty fine. But we are on DXP with Tomcat, so it could be different there.<br />Have you tried to use jaxrs:check in the gogo shell when the service fails?<br />Maybe it is waiting for an extension, jaxb-json maybe?Christoph Rabel2020-07-07T16:22:37ZRE: When service is not available, JAX-RS service returns 404 and not 500 wKevin Matthewshttps://liferay.dev/en/c/message_boards/find_message?p_l_id=119785333&messageId=1195552232020-07-07T14:35:28Z2020-07-07T14:35:28ZHi Chris, our underlying real problem is when the clients call /o/portal-api and receives a 404 its misleading because it could mean the following i.e service is unavailable or not Found or no data is in the DB for that lookup account. Before, we programmatically send a 404 to the client when there is no data in the DB for that account. So, now we have decided to return a 204 to define there is no data in the DB so it doesn't conflict with 404. If the client call the <span style="font-size: 16px;">/o/portal-api </span><span style="font-size: 16px;">service on Server A and they recieve a 404, then they can failover to Server B thats run the same API /o/portal-api , at some point this service may be available. In addition and more importantly, what I have notice when we upgraded from Liferay 7.0 to Liferay 7.2 , that the JAX-RS service does not seem to be as stable as 7.0 JAX-RS implementation. We did not use the migration tool but we just manually installed liferay 7.2 (Wildfly on CentOS linux.) I notice sometimes that the JAX-RS service bundle is ACTIVE but I get a 404 on /o/portal-api as shown below for some reason I don't know. I do not know why sometimes intermittently the service is unavailable or 404 not found. I have looked in the liferay log and there is no error nor bundle errors. What I do to resolve the error, is delete the osgi/state folder and restart the liferay server instance. This can be troubling/worrisome as we are going to move to PROD in 2 weeks.</span><br /><strong>HTTP/1.1 404 Not Found<br />Connection: keep-alive<br />Content-Length: 74<br />Content-Type: text/html<br />Date: Tue, 07 Jul 2020 13:38:22 GMT</strong><strong><html><head><title>Error</title></head><body>404 - Not Found</body></html></strong>Have you seen any intermittent issues with LR7.2 JAX-RX that produces services not available 404 ? <br /> I remember you told me to remove the state folder because sometimes if there is a lot of development work the bundles wont installed properly.<br /><div class="quote-title">Christoph Rabel:</div><blockquote><br />That's a specific service description and describes what return codes you can expect from e.g. PUT framework/startlevel or POST framework/bundles. I don't see how this is relevant here.<br />In any case, I don't think you can easily make /o/portal-api return 501/503 instead of 404 for services that are not there. You could maybe add your own filter and do some convoluted checks, but I am convinced that this will lead to a robust solution.<br />What is your underlying, real problem?<br />Is your service already returning 404 in some cases? The easiest solution would then be to change the return code and return maybe 204 (request was fine, but there is no content for you).<br />I am also not sure, where you need the information that the service is unavailable. It won't help you in the frontend anyway, whether you get a 404 or 503.<br />But it is often important to get an alert when a service is unavailable. What we usually do is to add a healthCheck method that basically returns "200 OK" when the service is working (often it doesn't do anything else). We use a tool to check that status regularly to check if all services are still up and working. Usually the check is also called immediately after deployments by a test-script to simply make sure that all rest services are still available and return sensible results.</blockquote>Kevin Matthews2020-07-07T14:35:28ZRE: When service is not available, JAX-RS service returns 404 and not 500 wChristoph Rabelhttps://liferay.dev/en/c/message_boards/find_message?p_l_id=119785333&messageId=1195233232020-07-02T16:06:07Z2020-07-02T16:06:07ZThat's a specific service description and describes what return codes you can expect from e.g. PUT framework/startlevel or POST framework/bundles. I don't see how this is relevant here.<br />In any case, I don't think you can easily make /o/portal-api return 501/503 instead of 404 for services that are not there. You could maybe add your own filter and do some convoluted checks, but I am convinced that this will lead to a robust solution.<br />What is your underlying, real problem?<br />Is your service already returning 404 in some cases? The easiest solution would then be to change the return code and return maybe 204 (request was fine, but there is no content for you).<br />I am also not sure, where you need the information that the service is unavailable. It won't help you in the frontend anyway, whether you get a 404 or 503.<br />But it is often important to get an alert when a service is unavailable. What we usually do is to add a healthCheck method that basically returns "200 OK" when the service is working (often it doesn't do anything else). We use a tool to check that status regularly to check if all services are still up and working. Usually the check is also called immediately after deployments by a test-script to simply make sure that all rest services are still available and return sensible results.Christoph Rabel2020-07-02T16:06:07ZRE: When service is not available, JAX-RS service returns 404 and not 500 wKevin Matthewshttps://liferay.dev/en/c/message_boards/find_message?p_l_id=119785333&messageId=1195261532020-07-02T14:11:40Z2020-07-02T14:11:40ZHi David, I am thinking returning a 204 (no content) to the client when the actual record is not there. The reason is there are specific conditions the client needs to do base on the response code either alter a message or fail over to a backup service depending on the response code. It seems there is a debate when I googled the usage of 404/204/200 as to what response code to use when looking up value that doesn't exist and it shares both your point and Chris point when to use 404. <br /><div class="quote-title">David H Nebinger:</div><blockquote><br />Christoph describes the purely philosophical view for a missing /o/portal-api.<br /><br />But we don't live in a purely philosophical world. A hacker will want to try and take advantage of an /o/portal-api endpoint that returns 501 or 503, either as an attack vector to gain entry or simply as a way to try to crash the node.<br /><br />Besides that, you're expecting the portal to know that /o/portal-api is supposed to exist and is therefore missing and should be reported as a 501/503. The portal is not going to know this. You might have purposefully undeployed or disabled the module that /o/portal-api represents, there may be some dependency issue which would prevent forever /o/portal-api from starting, ...<br /><br /><br />There is context behind /o/portal-api not being there, in this case Kevin reviews the context and believes it is due to a missing service and is therefore a server error, but the portal itself can not and should not be trying to guess on its own. Returning a 404 is the cleanest and simplest and, I would argue, best path the portal should take in this situation.</blockquote>Kevin Matthews2020-07-02T14:11:40ZRE: When service is not available, JAX-RS service returns 404 and not 500 wKevin Matthewshttps://liferay.dev/en/c/message_boards/find_message?p_l_id=119785333&messageId=1195258032020-07-02T13:59:08Z2020-07-02T13:59:08ZHi Chris, looking through the osgi spec on a GET request 404 , is define as there is no bundle on giving bundle id. But there is no 404 on a POST. It seems from OSGI perspective if a bundle is not activated or in a resolve or inactive state then its 404 response <a href="https://docs.osgi.org/specification/osgi.cmpn/7.0.0/service.rest.html">https://docs.osgi.org/specification/osgi.cmpn/7.0.0/service.rest.html</a>. <br /> How do I make /o/portal-api a 501 or 503 in my application on a POST request when the service is unavailable (REST bundle) or in resolved state?<div class="quote-title">Christoph Rabel:</div><blockquote><br />That's a hard one. Because it is a bit philosophical.<br />4xx are client errors (caused by the client), 404 means that the client (his error) asked for stuff that isn't there.<br />5xx are server errors.<br />That's the theory, but practically speaking, that 4xx is a client error, 5xx is a server error, is not always easy to make and there's a lot of ambiguity here.<br />What should a request for "/o/portla-api" return? That url and server does not exist and the error (typo) is in the client. 404 would be correct here, the client has to use a different url.<br />But for "/o/portal-api" something like 501(Not implemented) or 503(Service unavailable) would be more precise since the service could actually exist, even though it is not deployed. So, the client is right and the server should be "fixed".<br />I am not sure what would be best here. Maybe 501 would actually be the best solution. Something is asking for a service and the backend says: Sorry, not implemented. But 404 is not really wrong.</blockquote>Kevin Matthews2020-07-02T13:59:08ZRE: When service is not available, JAX-RS service returns 404 and not 500 wDavid H Nebingerhttps://liferay.dev/en/c/message_boards/find_message?p_l_id=119785333&messageId=1195210922020-07-02T12:57:43Z2020-07-02T12:57:43ZChristoph describes the purely philosophical view for a missing /o/portal-api.<br /><br />But we don't live in a purely philosophical world. A hacker will want to try and take advantage of an /o/portal-api endpoint that returns 501 or 503, either as an attack vector to gain entry or simply as a way to try to crash the node.<br /><br />Besides that, you're expecting the portal to know that /o/portal-api is supposed to exist and is therefore missing and should be reported as a 501/503. The portal is not going to know this. You might have purposefully undeployed or disabled the module that /o/portal-api represents, there may be some dependency issue which would prevent forever /o/portal-api from starting, ...<br /><br /><br />There is context behind /o/portal-api not being there, in this case Kevin reviews the context and believes it is due to a missing service and is therefore a server error, but the portal itself can not and should not be trying to guess on its own. Returning a 404 is the cleanest and simplest and, I would argue, best path the portal should take in this situation.David H Nebinger2020-07-02T12:57:43ZRE: When service is not available, JAX-RS service returns 404 and not 500 wChristoph Rabelhttps://liferay.dev/en/c/message_boards/find_message?p_l_id=119785333&messageId=1195197932020-07-02T07:30:54Z2020-07-02T07:30:54ZThat's a hard one. Because it is a bit philosophical.<br />4xx are client errors (caused by the client), 404 means that the client (his error) asked for stuff that isn't there.<br />5xx are server errors.<br />That's the theory, but practically speaking, that 4xx is a client error, 5xx is a server error, is not always easy to make and there's a lot of ambiguity here.<br />What should a request for "/o/portla-api" return? That url and server does not exist and the error (typo) is in the client. 404 would be correct here, the client has to use a different url.<br />But for "/o/portal-api" something like 501(Not implemented) or 503(Service unavailable) would be more precise since the service could actually exist, even though it is not deployed. So, the client is right and the server should be "fixed".<br />I am not sure what would be best here. Maybe 501 would actually be the best solution. Something is asking for a service and the backend says: Sorry, not implemented. But 404 is not really wrong.Christoph Rabel2020-07-02T07:30:54ZRE: When service is not available, JAX-RS service returns 404 and not 500 wKevin Matthewshttps://liferay.dev/en/c/message_boards/find_message?p_l_id=119785333&messageId=1195216922020-07-01T23:44:59Z2020-07-01T23:44:59Z<p>Hi David, yes I agree 500 is a server error. But isnt 404 is no resources found, for example lookup an account number in DB or specfically a resource url does not exist. If we stop the bundle and no services available does that mean a 404?&nbsp; How do we treat JAX-RS response codes for inactive or bundles in resolved state &quot;no services available?</p>Kevin Matthews2020-07-01T23:44:59ZRE: When service is not available, JAX-RS service returns 404 and not 500 wDavid H Nebingerhttps://liferay.dev/en/c/message_boards/find_message?p_l_id=119785333&messageId=1195193292020-07-01T20:20:02Z2020-07-01T20:20:02Z500 represents a server error. There is no server error here.<br /><br /><br />The URL you requested is, in fact, not found and therefore the 404 is absolutely appropriate.David H Nebinger2020-07-01T20:20:02ZWhen service is not available, JAX-RS service returns 404 and not 500 why?Kevin Matthewshttps://liferay.dev/en/c/message_boards/find_message?p_l_id=119785333&messageId=1195191422020-07-01T17:40:53Z2020-07-01T17:40:53Z