Search in sources :

Example 1 with HandlerException

use of co.cask.cdap.common.HandlerException in project cdap by caskdata.

the class DatasetInstanceHandler method executeAdmin.

/**
   * Executes an admin operation on a dataset instance.
   *
   * @param namespaceId namespace of the dataset instance
   * @param name name of the dataset instance
   * @param method the admin operation to execute (e.g. "exists", "truncate", "upgrade")
   * @throws Exception
   */
@POST
@Path("/data/datasets/{name}/admin/{method}")
public void executeAdmin(HttpRequest request, HttpResponder responder, @PathParam("namespace-id") String namespaceId, @PathParam("name") String name, @PathParam("method") String method) throws Exception {
    DatasetId instance = ConversionHelpers.toDatasetInstanceId(namespaceId, name);
    try {
        DatasetAdminOpResponse response = instanceService.executeAdmin(instance, method);
        responder.sendJson(HttpResponseStatus.OK, response);
    } catch (HandlerException e) {
        responder.sendStatus(e.getFailureStatus());
    }
}
Also used : HandlerException(co.cask.cdap.common.HandlerException) DatasetAdminOpResponse(co.cask.cdap.data2.datafabric.dataset.service.executor.DatasetAdminOpResponse) DatasetId(co.cask.cdap.proto.id.DatasetId) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST)

Example 2 with HandlerException

use of co.cask.cdap.common.HandlerException in project cdap by caskdata.

the class DatasetInstanceService method executeAdmin.

/**
   * Executes an admin operation on a dataset instance.
   *
   * @param instance the instance to execute the admin operation on
   * @param method the type of admin operation to execute
   * @return the {@link DatasetAdminOpResponse} from the HTTP handler
   * @throws NamespaceNotFoundException if the requested namespace was not found
   * @throws IOException if there was a problem in checking if the namespace exists over HTTP
   * @throws UnauthorizedException if perimeter security and authorization are enabled, and the current user does not
   *  have -
   *  <ol>
   *    <li>{@link Action#ADMIN} privileges on the #instance (for "drop" or "truncate") </li>
   *    <li>any privileges on the #instance (for "exists")</li>
   *  <ol>
   */
DatasetAdminOpResponse executeAdmin(DatasetId instance, String method) throws Exception {
    ensureNamespaceExists(instance.getParent());
    Object result = null;
    // NOTE: one cannot directly call create and drop, instead this should be called thru
    //       POST/DELETE @ /data/datasets/{instance-id}. Because we must create/drop metadata for these at same time
    Principal principal = authenticationContext.getPrincipal();
    switch(method) {
        case "exists":
            ensureAccess(instance);
            result = opExecutorClient.exists(instance);
            break;
        case "truncate":
            if (instanceManager.get(instance) == null) {
                throw new DatasetNotFoundException(instance);
            }
            authorizationEnforcer.enforce(instance, principal, Action.ADMIN);
            opExecutorClient.truncate(instance);
            publishAudit(instance, AuditType.TRUNCATE);
            break;
        case "upgrade":
            if (instanceManager.get(instance) == null) {
                throw new DatasetNotFoundException(instance);
            }
            authorizationEnforcer.enforce(instance, principal, Action.ADMIN);
            opExecutorClient.upgrade(instance);
            publishAudit(instance, AuditType.UPDATE);
            break;
        default:
            throw new HandlerException(HttpResponseStatus.NOT_FOUND, "Invalid admin operation: " + method);
    }
    return new DatasetAdminOpResponse(result, null);
}
Also used : HandlerException(co.cask.cdap.common.HandlerException) DatasetNotFoundException(co.cask.cdap.common.DatasetNotFoundException) DatasetAdminOpResponse(co.cask.cdap.data2.datafabric.dataset.service.executor.DatasetAdminOpResponse) Principal(co.cask.cdap.proto.security.Principal)

Example 3 with HandlerException

use of co.cask.cdap.common.HandlerException in project cdap by caskdata.

the class HttpRequestHandler method exceptionCaught.

@Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
    Throwable cause = e.getCause();
    // avoid handling exception more than once from a handler, to avoid a possible infinite recursion
    switch(exceptionsHandled.incrementAndGet()) {
        case 1:
            // if this is the first error, break and handle the error normally (below)
            break;
        case 2:
            // if its the second time, log and return
            LOG.error("Not handling exception due to already having handled an exception in Request Handler {}", ctx.getChannel(), cause);
        // fall through
        default:
            // in an exception and cause recursion
            return;
    }
    if (cause instanceof HandlerException && ((HandlerException) cause).getFailureStatus() != HttpResponseStatus.INTERNAL_SERVER_ERROR) {
        LOG.debug("Exception raised in Request Handler {}", ctx.getChannel(), cause);
    } else {
        LOG.error("Exception raised in Request Handler {}", ctx.getChannel(), cause);
    }
    if (ctx.getChannel().isConnected() && !channelClosed) {
        HttpResponse response = cause instanceof HandlerException ? ((HandlerException) cause).createFailureResponse() : new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.INTERNAL_SERVER_ERROR);
        Channels.write(ctx, e.getFuture(), response);
        e.getFuture().addListener(ChannelFutureListener.CLOSE);
    }
}
Also used : HandlerException(co.cask.cdap.common.HandlerException) DefaultHttpResponse(org.jboss.netty.handler.codec.http.DefaultHttpResponse) DefaultHttpResponse(org.jboss.netty.handler.codec.http.DefaultHttpResponse) HttpResponse(org.jboss.netty.handler.codec.http.HttpResponse)

Example 4 with HandlerException

use of co.cask.cdap.common.HandlerException in project cdap by caskdata.

the class HttpRequestHandler method getDiscoverable.

private WrappedDiscoverable getDiscoverable(final HttpRequest httpRequest, final InetSocketAddress address) {
    EndpointStrategy strategy = serviceLookup.getDiscoverable(address.getPort(), httpRequest);
    if (strategy == null) {
        throw new HandlerException(HttpResponseStatus.SERVICE_UNAVAILABLE, String.format("No endpoint strategy found for request : %s", httpRequest.getUri()));
    }
    Discoverable discoverable = strategy.pick();
    if (discoverable == null) {
        throw new HandlerException(HttpResponseStatus.SERVICE_UNAVAILABLE, String.format("No discoverable found for request : %s", httpRequest.getUri()));
    }
    return new WrappedDiscoverable(discoverable);
}
Also used : HandlerException(co.cask.cdap.common.HandlerException) Discoverable(org.apache.twill.discovery.Discoverable) EndpointStrategy(co.cask.cdap.common.discovery.EndpointStrategy)

Example 5 with HandlerException

use of co.cask.cdap.common.HandlerException in project cdap by caskdata.

the class HttpRequestHandler method messageReceived.

@Override
public void messageReceived(final ChannelHandlerContext ctx, MessageEvent event) throws Exception {
    if (channelClosed) {
        return;
    }
    final Channel inboundChannel = event.getChannel();
    Object msg = event.getMessage();
    if (msg instanceof HttpChunk) {
        // This case below should never happen this would mean we get Chunks before HTTPMessage.
        if (chunkSender == null) {
            throw new HandlerException(HttpResponseStatus.INTERNAL_SERVER_ERROR, "Chunk received and event sender is null");
        }
        chunkSender.send(msg);
    } else if (msg instanceof HttpRequest) {
        // Discover and forward event.
        HttpRequest request = (HttpRequest) msg;
        request = applyProxyRules(request);
        // Suspend incoming traffic until connected to the outbound service.
        inboundChannel.setReadable(false);
        WrappedDiscoverable discoverable = getDiscoverable(request, (InetSocketAddress) inboundChannel.getLocalAddress());
        // If no event sender, make new connection, otherwise reuse existing one.
        MessageSender sender = discoveryLookup.get(discoverable);
        if (sender == null || !sender.isConnected()) {
            InetSocketAddress address = discoverable.getSocketAddress();
            ChannelFuture future = clientBootstrap.connect(address);
            final Channel outboundChannel = future.getChannel();
            outboundChannel.getPipeline().addAfter("request-encoder", "outbound-handler", new OutboundHandler(inboundChannel));
            if (Arrays.equals(Constants.Security.SSL_URI_SCHEME.getBytes(), discoverable.getPayload())) {
                SSLContext clientContext;
                try {
                    clientContext = SSLContext.getInstance("TLS");
                    clientContext.init(null, PermissiveTrustManagerFactory.getTrustManagers(), null);
                } catch (NoSuchAlgorithmException | KeyManagementException e) {
                    throw new RuntimeException("SSL is enabled for app-fabric but failed to create SSLContext in the router " + "client.", e);
                }
                SSLEngine engine = clientContext.createSSLEngine();
                engine.setUseClientMode(true);
                engine.setEnabledProtocols(new String[] { "TLSv1.2", "TLSv1.1", "TLSv1" });
                outboundChannel.getPipeline().addFirst("ssl", new SslHandler(engine));
                LOG.trace("Adding ssl handler to the pipeline.");
            }
            sender = new MessageSender(inboundChannel, future);
            discoveryLookup.put(discoverable, sender);
            // Remember the in-flight outbound channel
            inboundChannel.setAttachment(outboundChannel);
            outboundChannel.getCloseFuture().addListener(new ChannelFutureListener() {

                @Override
                public void operationComplete(ChannelFuture future) throws Exception {
                    inboundChannel.getPipeline().execute(new Runnable() {

                        @Override
                        public void run() {
                            // close the inbound channel as well if it carries the in-flight request
                            if (outboundChannel.equals(inboundChannel.getAttachment())) {
                                closeOnFlush(inboundChannel);
                            }
                        }
                    });
                }
            });
        } else {
            Channel outboundChannel = (Channel) inboundChannel.getAttachment();
            if (outboundChannel != null) {
                // Set outbound channel to be readable in case previous request has set it as non-readable
                outboundChannel.setReadable(true);
            }
        }
        // Send the message.
        sender.send(request);
        inboundChannel.setReadable(true);
        //Save the channelFuture for subsequent chunks
        if (request.isChunked()) {
            chunkSender = sender;
        }
    } else {
        super.messageReceived(ctx, event);
    }
}
Also used : HttpRequest(org.jboss.netty.handler.codec.http.HttpRequest) ChannelFuture(org.jboss.netty.channel.ChannelFuture) HandlerException(co.cask.cdap.common.HandlerException) InetSocketAddress(java.net.InetSocketAddress) SSLEngine(javax.net.ssl.SSLEngine) Channel(org.jboss.netty.channel.Channel) SSLContext(javax.net.ssl.SSLContext) ChannelFutureListener(org.jboss.netty.channel.ChannelFutureListener) SslHandler(org.jboss.netty.handler.ssl.SslHandler) HttpChunk(org.jboss.netty.handler.codec.http.HttpChunk)

Aggregations

HandlerException (co.cask.cdap.common.HandlerException)6 DatasetAdminOpResponse (co.cask.cdap.data2.datafabric.dataset.service.executor.DatasetAdminOpResponse)2 Path (javax.ws.rs.Path)2 DatasetAlreadyExistsException (co.cask.cdap.common.DatasetAlreadyExistsException)1 DatasetNotFoundException (co.cask.cdap.common.DatasetNotFoundException)1 DatasetTypeNotFoundException (co.cask.cdap.common.DatasetTypeNotFoundException)1 EndpointStrategy (co.cask.cdap.common.discovery.EndpointStrategy)1 AuditPolicy (co.cask.cdap.common.security.AuditPolicy)1 DatasetInstanceConfiguration (co.cask.cdap.proto.DatasetInstanceConfiguration)1 DatasetId (co.cask.cdap.proto.id.DatasetId)1 Principal (co.cask.cdap.proto.security.Principal)1 InetSocketAddress (java.net.InetSocketAddress)1 SSLContext (javax.net.ssl.SSLContext)1 SSLEngine (javax.net.ssl.SSLEngine)1 POST (javax.ws.rs.POST)1 PUT (javax.ws.rs.PUT)1 Discoverable (org.apache.twill.discovery.Discoverable)1 Channel (org.jboss.netty.channel.Channel)1 ChannelFuture (org.jboss.netty.channel.ChannelFuture)1 ChannelFutureListener (org.jboss.netty.channel.ChannelFutureListener)1