Example usage for org.apache.http.client.protocol HttpClientContext getCredentialsProvider

List of usage examples for org.apache.http.client.protocol HttpClientContext getCredentialsProvider

Introduction

In this page you can find the example usage for org.apache.http.client.protocol HttpClientContext getCredentialsProvider.

Prototype

public CredentialsProvider getCredentialsProvider() 

Source Link

Usage

From source file:org.apache.openmeetings.service.calendar.caldav.AppointmentManager.java

/**
 * Adds the Credentials provided to the given client on the Calendar's URL.
 *
 * @param context     Context of the Client which makes the connection.
 * @param calendar    Calendar whose Host the Credentials are for.
 * @param credentials Credentials to add
 *//*from   w  w  w .j  a  v  a2  s .c om*/
public void provideCredentials(HttpClientContext context, OmCalendar calendar, Credentials credentials) {
    // Done through creating a new Local context
    if (!Strings.isEmpty(calendar.getHref()) && credentials != null) {
        URI temp = URI.create(calendar.getHref());
        context.getCredentialsProvider().setCredentials(new AuthScope(temp.getHost(), temp.getPort()),
                credentials);
    }
}

From source file:org.opensaml.security.httpclient.HttpClientSecuritySupportTest.java

@Test
public void testMarshalSecurityParametersEmptyContext() {
    HttpClientContext context = HttpClientContext.create();

    HttpClientSecurityParameters params = new HttpClientSecurityParameters();
    params.setCredentialsProvider(new BasicCredentialsProvider());
    params.setTLSTrustEngine(new MockTrustEngine());
    params.setTLSCriteriaSet(new CriteriaSet());
    params.setTLSProtocols(Lists.newArrayList("foo"));
    params.setTLSCipherSuites(Lists.newArrayList("foo"));
    params.setClientTLSCredential(new BasicX509Credential(cert));
    params.setHostnameVerifier(new StrictHostnameVerifier());

    HttpClientSecuritySupport.marshalSecurityParameters(context, params, false);

    Assert.assertSame(context.getCredentialsProvider(), params.getCredentialsProvider());
    Assert.assertSame(context.getAttribute(CONTEXT_KEY_TRUST_ENGINE), params.getTLSTrustEngine());
    Assert.assertSame(context.getAttribute(CONTEXT_KEY_CRITERIA_SET), params.getTLSCriteriaSet());
    Assert.assertSame(context.getAttribute(CONTEXT_KEY_TLS_PROTOCOLS), params.getTLSProtocols());
    Assert.assertSame(context.getAttribute(CONTEXT_KEY_TLS_CIPHER_SUITES), params.getTLSCipherSuites());
    Assert.assertSame(context.getAttribute(CONTEXT_KEY_CLIENT_TLS_CREDENTIAL), params.getClientTLSCredential());
    Assert.assertSame(context.getAttribute(CONTEXT_KEY_HOSTNAME_VERIFIER), params.getHostnameVerifier());
}

From source file:de.undercouch.gradle.tasks.download.DownloadAction.java

/**
 * Add authentication information for the given host
 * @param host the host/*from w  w  w. java 2s .c  o m*/
 * @param credentials the credentials
 * @param authScheme the scheme for preemptive authentication (should be
 * <code>null</code> if adding authentication for a proxy server)
 * @param context the context in which the authentication information
 * should be saved
 */
private void addAuthentication(HttpHost host, Credentials credentials, AuthScheme authScheme,
        HttpClientContext context) {
    AuthCache authCache = context.getAuthCache();
    if (authCache == null) {
        authCache = new BasicAuthCache();
        context.setAuthCache(authCache);
    }

    CredentialsProvider credsProvider = context.getCredentialsProvider();
    if (credsProvider == null) {
        credsProvider = new BasicCredentialsProvider();
        context.setCredentialsProvider(credsProvider);
    }

    credsProvider.setCredentials(new AuthScope(host), credentials);

    if (authScheme != null) {
        authCache.put(host, authScheme);
    }
}

From source file:org.opensaml.soap.client.http.AbstractPipelineHttpSOAPClient.java

/**
 * Build the {@link HttpClientContext} instance to be used by the HttpClient.
 * //from w w  w . j  a v  a  2s .  c  o  m
 * @param request the HTTP client request
 * @param operationContext the current operation context
 * @return the client context instance
 */
@Nonnull
protected HttpClientContext buildHttpContext(@Nonnull final HttpUriRequest request,
        @Nonnull final InOutOperationContext operationContext) {

    HttpClientContext httpClientContext = resolveHttpContext(operationContext);

    HttpClientSecurityParameters securityParameters = operationContext.getOutboundMessageContext()
            .getSubcontext(HttpClientSecurityContext.class, true).getSecurityParameters();

    CredentialsProvider credProvider = ObjectSupport.firstNonNull(
            securityParameters != null ? securityParameters.getCredentialsProvider() : null,
            httpClientContext.getCredentialsProvider(), getCredentialsProvider());
    if (credProvider != null) {
        httpClientContext.setCredentialsProvider(credProvider);
    }

    populateTLSContextParameters(httpClientContext, securityParameters, request, operationContext);

    return httpClientContext;
}

From source file:org.apache.sling.discovery.base.connectors.ping.TopologyConnectorClient.java

/** Disconnect this connector **/
public void disconnect() {
    final String uri = connectorUrl.toString() + "." + clusterViewService.getSlingId() + ".json";
    if (logger.isDebugEnabled()) {
        logger.debug("disconnect: connectorUrl=" + connectorUrl + ", complete uri=" + uri);
    }/*from   w ww. ja va 2  s.co m*/

    if (lastInheritedAnnouncement != null) {
        announcementRegistry.unregisterAnnouncement(lastInheritedAnnouncement.getOwnerId());
    }

    final HttpClientContext clientContext = HttpClientContext.create();
    final CloseableHttpClient httpClient = createHttpClient();
    final HttpDelete deleteRequest = new HttpDelete(uri);
    // setting the connection timeout (idle connection, configured in seconds)
    deleteRequest.setConfig(
            RequestConfig.custom().setConnectTimeout(1000 * config.getSocketConnectTimeout()).build());

    try {
        String userInfo = connectorUrl.getUserInfo();
        if (userInfo != null) {
            Credentials c = new UsernamePasswordCredentials(userInfo);
            clientContext.getCredentialsProvider().setCredentials(
                    new AuthScope(deleteRequest.getURI().getHost(), deleteRequest.getURI().getPort()), c);
        }

        requestValidator.trustMessage(deleteRequest, null);
        final CloseableHttpResponse response = httpClient.execute(deleteRequest, clientContext);
        if (logger.isDebugEnabled()) {
            logger.debug("disconnect: done. code=" + response.getStatusLine().getStatusCode() + " - "
                    + response.getStatusLine().getReasonPhrase());
        }
        // ignoring the actual statuscode though as there's little we can
        // do about it after this point
    } catch (IOException e) {
        logger.warn("disconnect: got IOException: " + e);
    } catch (RuntimeException re) {
        logger.error("disconnect: got RuntimeException: " + re, re);
    } finally {
        deleteRequest.releaseConnection();
        try {
            httpClient.close();
        } catch (IOException e) {
            logger.error("disconnect: could not close httpClient: " + e, e);
        }
    }
}

From source file:org.apache.sling.discovery.base.connectors.ping.TopologyConnectorClient.java

/** ping the server and pass the announcements between the two **/
void ping(final boolean force) {
    if (autoStopped) {
        // then we suppress any further pings!
        logger.debug("ping: autoStopped=true, hence suppressing any further pings.");
        return;//from  w  w  w.j a  v a2  s  . c o m
    }
    if (force) {
        backoffPeriodEnd = -1;
    } else if (backoffPeriodEnd > 0) {
        if (System.currentTimeMillis() < backoffPeriodEnd) {
            logger.debug("ping: not issueing a heartbeat due to backoff instruction from peer.");
            return;
        } else {
            logger.debug("ping: backoff period ended, issuing another ping now.");
        }
    }
    final String uri = connectorUrl.toString() + "." + clusterViewService.getSlingId() + ".json";
    if (logger.isDebugEnabled()) {
        logger.debug("ping: connectorUrl=" + connectorUrl + ", complete uri=" + uri);
    }
    final HttpClientContext clientContext = HttpClientContext.create();
    final CloseableHttpClient httpClient = createHttpClient();
    final HttpPut putRequest = new HttpPut(uri);

    // setting the connection timeout (idle connection, configured in seconds)
    putRequest.setConfig(
            RequestConfig.custom().setConnectTimeout(1000 * config.getSocketConnectTimeout()).build());

    Announcement resultingAnnouncement = null;
    try {
        String userInfo = connectorUrl.getUserInfo();
        if (userInfo != null) {
            Credentials c = new UsernamePasswordCredentials(userInfo);
            clientContext.getCredentialsProvider().setCredentials(
                    new AuthScope(putRequest.getURI().getHost(), putRequest.getURI().getPort()), c);
        }

        Announcement topologyAnnouncement = new Announcement(clusterViewService.getSlingId());
        topologyAnnouncement.setServerInfo(serverInfo);
        final ClusterView clusterView;
        try {
            clusterView = clusterViewService.getLocalClusterView();
        } catch (UndefinedClusterViewException e) {
            // SLING-5030 : then we cannot ping
            logger.warn("ping: no clusterView available at the moment, cannot ping others now: " + e);
            return;
        }
        topologyAnnouncement.setLocalCluster(clusterView);
        if (force) {
            logger.debug("ping: sending a resetBackoff");
            topologyAnnouncement.setResetBackoff(true);
        }
        announcementRegistry.addAllExcept(topologyAnnouncement, clusterView, new AnnouncementFilter() {

            public boolean accept(final String receivingSlingId, final Announcement announcement) {
                // filter out announcements that are of old cluster instances
                // which I dont really have in my cluster view at the moment
                final Iterator<InstanceDescription> it = clusterView.getInstances().iterator();
                while (it.hasNext()) {
                    final InstanceDescription instance = it.next();
                    if (instance.getSlingId().equals(receivingSlingId)) {
                        // then I have the receiving instance in my cluster view
                        // all fine then
                        return true;
                    }
                }
                // looks like I dont have the receiving instance in my cluster view
                // then I should also not propagate that announcement anywhere
                return false;
            }
        });
        final String p = requestValidator.encodeMessage(topologyAnnouncement.asJSON());

        if (logger.isDebugEnabled()) {
            logger.debug("ping: topologyAnnouncement json is: " + p);
        }
        requestValidator.trustMessage(putRequest, p);
        if (config.isGzipConnectorRequestsEnabled()) {
            // tell the server that the content is gzipped:
            putRequest.addHeader("Content-Encoding", "gzip");
            // and gzip the body:
            final ByteArrayOutputStream baos = new ByteArrayOutputStream();
            final GZIPOutputStream gzipOut = new GZIPOutputStream(baos);
            gzipOut.write(p.getBytes("UTF-8"));
            gzipOut.close();
            final byte[] gzippedEncodedJson = baos.toByteArray();
            putRequest.setEntity(new ByteArrayEntity(gzippedEncodedJson, ContentType.APPLICATION_JSON));
            lastRequestEncoding = "gzip";
        } else {
            // otherwise plaintext:
            final StringEntity plaintext = new StringEntity(p, "UTF-8");
            plaintext.setContentType(ContentType.APPLICATION_JSON.getMimeType());
            putRequest.setEntity(plaintext);
            lastRequestEncoding = "plaintext";
        }
        // independent of request-gzipping, we do accept the response to be gzipped,
        // so indicate this to the server:
        putRequest.addHeader("Accept-Encoding", "gzip");
        final CloseableHttpResponse response = httpClient.execute(putRequest, clientContext);
        if (logger.isDebugEnabled()) {
            logger.debug("ping: done. code=" + response.getStatusLine().getStatusCode() + " - "
                    + response.getStatusLine().getReasonPhrase());
        }
        lastStatusCode = response.getStatusLine().getStatusCode();
        lastResponseEncoding = null;
        if (response.getStatusLine().getStatusCode() == HttpServletResponse.SC_OK) {
            final Header contentEncoding = response.getFirstHeader("Content-Encoding");
            if (contentEncoding != null && contentEncoding.getValue() != null
                    && contentEncoding.getValue().contains("gzip")) {
                lastResponseEncoding = "gzip";
            } else {
                lastResponseEncoding = "plaintext";
            }
            final String responseBody = requestValidator.decodeMessage(putRequest.getURI().getPath(), response); // limiting to 16MB, should be way enough
            if (logger.isDebugEnabled()) {
                logger.debug("ping: response body=" + responseBody);
            }
            if (responseBody != null && responseBody.length() > 0) {
                Announcement inheritedAnnouncement = Announcement.fromJSON(responseBody);
                final long backoffInterval = inheritedAnnouncement.getBackoffInterval();
                if (backoffInterval > 0) {
                    // then reset the backoffPeriodEnd:

                    /* minus 1 sec to avoid slipping the interval by a few millis */
                    this.backoffPeriodEnd = System.currentTimeMillis() + (1000 * backoffInterval) - 1000;
                    logger.debug("ping: servlet instructed to backoff: backoffInterval=" + backoffInterval
                            + ", resulting in period end of " + new Date(backoffPeriodEnd));
                } else {
                    logger.debug("ping: servlet did not instruct any backoff-ing at this stage");
                    this.backoffPeriodEnd = -1;
                }
                if (inheritedAnnouncement.isLoop()) {
                    if (logger.isDebugEnabled()) {
                        logger.debug(
                                "ping: connector response indicated a loop detected. not registering this announcement from "
                                        + inheritedAnnouncement.getOwnerId());
                    }
                    if (inheritedAnnouncement.getOwnerId().equals(clusterViewService.getSlingId())) {
                        // SLING-3316 : local-loop detected. Check config to see if we should stop this connector

                        if (config.isAutoStopLocalLoopEnabled()) {
                            inheritedAnnouncement = null; // results in connected -> false and representsloop -> true
                            autoStopped = true; // results in isAutoStopped -> true
                        }
                    }
                } else {
                    inheritedAnnouncement.setInherited(true);
                    if (announcementRegistry.registerAnnouncement(inheritedAnnouncement) == -1) {
                        if (logger.isDebugEnabled()) {
                            logger.debug(
                                    "ping: connector response is from an instance which I already see in my topology"
                                            + inheritedAnnouncement);
                        }
                        statusDetails = "receiving side is seeing me via another path (connector or cluster) already (loop)";
                        return;
                    }
                }
                resultingAnnouncement = inheritedAnnouncement;
                statusDetails = null;
            } else {
                statusDetails = "no response body received";
            }
        } else {
            statusDetails = "got HTTP Status-Code: " + lastStatusCode;
        }
        // SLING-2882 : reset suppressPingWarnings_ flag in success case
        suppressPingWarnings_ = false;
    } catch (IOException e) {
        // SLING-2882 : set/check the suppressPingWarnings_ flag
        if (suppressPingWarnings_) {
            if (logger.isDebugEnabled()) {
                logger.debug("ping: got IOException: " + e + ", uri=" + uri);
            }
        } else {
            suppressPingWarnings_ = true;
            logger.warn("ping: got IOException [suppressing further warns]: " + e + ", uri=" + uri);
        }
        statusDetails = e.toString();
    } catch (JSONException e) {
        logger.warn("ping: got JSONException: " + e);
        statusDetails = e.toString();
    } catch (RuntimeException re) {
        logger.warn("ping: got RuntimeException: " + re, re);
        statusDetails = re.toString();
    } finally {
        putRequest.releaseConnection();
        lastInheritedAnnouncement = resultingAnnouncement;
        lastPingedAt = System.currentTimeMillis();
        try {
            httpClient.close();
        } catch (IOException e) {
            logger.error("disconnect: could not close httpClient: " + e, e);
        }
    }
}

From source file:org.opensaml.security.httpclient.HttpClientSecuritySupportTest.java

@Test
public void testMarshalSecurityParametersWithReplacement() {
    HttpClientContext context = HttpClientContext.create();

    context.setCredentialsProvider(new BasicCredentialsProvider());
    context.setAttribute(CONTEXT_KEY_TRUST_ENGINE, new MockTrustEngine());
    context.setAttribute(CONTEXT_KEY_CRITERIA_SET, new CriteriaSet());
    context.setAttribute(CONTEXT_KEY_TLS_PROTOCOLS, Lists.newArrayList("foo"));
    context.setAttribute(CONTEXT_KEY_TLS_CIPHER_SUITES, Lists.newArrayList("foo"));
    context.setAttribute(CONTEXT_KEY_CLIENT_TLS_CREDENTIAL, new BasicX509Credential(cert));
    context.setAttribute(CONTEXT_KEY_HOSTNAME_VERIFIER, new StrictHostnameVerifier());

    HttpClientSecurityParameters params = new HttpClientSecurityParameters();
    params.setCredentialsProvider(new BasicCredentialsProvider());
    params.setTLSTrustEngine(new MockTrustEngine());
    params.setTLSCriteriaSet(new CriteriaSet());
    params.setTLSProtocols(Lists.newArrayList("foo"));
    params.setTLSCipherSuites(Lists.newArrayList("foo"));
    params.setClientTLSCredential(new BasicX509Credential(cert));
    params.setHostnameVerifier(new StrictHostnameVerifier());

    HttpClientSecuritySupport.marshalSecurityParameters(context, params, true);

    Assert.assertSame(context.getCredentialsProvider(), params.getCredentialsProvider());
    Assert.assertSame(context.getAttribute(CONTEXT_KEY_TRUST_ENGINE), params.getTLSTrustEngine());
    Assert.assertSame(context.getAttribute(CONTEXT_KEY_CRITERIA_SET), params.getTLSCriteriaSet());
    Assert.assertSame(context.getAttribute(CONTEXT_KEY_TLS_PROTOCOLS), params.getTLSProtocols());
    Assert.assertSame(context.getAttribute(CONTEXT_KEY_TLS_CIPHER_SUITES), params.getTLSCipherSuites());
    Assert.assertSame(context.getAttribute(CONTEXT_KEY_CLIENT_TLS_CREDENTIAL), params.getClientTLSCredential());
    Assert.assertSame(context.getAttribute(CONTEXT_KEY_HOSTNAME_VERIFIER), params.getHostnameVerifier());
}

From source file:org.opensaml.security.httpclient.HttpClientSecuritySupportTest.java

@Test
public void testMarshalSecurityParametersWithoutReplacement() {
    HttpClientContext context = HttpClientContext.create();

    CredentialsProvider credProvider = new BasicCredentialsProvider();
    TrustEngine<X509Credential> trustEngine = new MockTrustEngine();
    CriteriaSet criteriaSet = new CriteriaSet();
    List<String> protocols = Lists.newArrayList("foo");
    List<String> cipherSuites = Lists.newArrayList("foo");
    X509Credential clientTLSCred = new BasicX509Credential(cert);
    HostnameVerifier verifier = new StrictHostnameVerifier();

    context.setCredentialsProvider(credProvider);
    context.setAttribute(CONTEXT_KEY_TRUST_ENGINE, trustEngine);
    context.setAttribute(CONTEXT_KEY_CRITERIA_SET, criteriaSet);
    context.setAttribute(CONTEXT_KEY_TLS_PROTOCOLS, protocols);
    context.setAttribute(CONTEXT_KEY_TLS_CIPHER_SUITES, cipherSuites);
    context.setAttribute(CONTEXT_KEY_CLIENT_TLS_CREDENTIAL, clientTLSCred);
    context.setAttribute(CONTEXT_KEY_HOSTNAME_VERIFIER, verifier);

    HttpClientSecurityParameters params = new HttpClientSecurityParameters();
    params.setCredentialsProvider(new BasicCredentialsProvider());
    params.setTLSTrustEngine(new MockTrustEngine());
    params.setTLSCriteriaSet(new CriteriaSet());
    params.setTLSProtocols(Lists.newArrayList("foo"));
    params.setTLSCipherSuites(Lists.newArrayList("foo"));
    params.setClientTLSCredential(new BasicX509Credential(cert));
    params.setHostnameVerifier(new StrictHostnameVerifier());

    HttpClientSecuritySupport.marshalSecurityParameters(context, params, false);

    Assert.assertSame(context.getCredentialsProvider(), credProvider);
    Assert.assertSame(context.getAttribute(CONTEXT_KEY_TRUST_ENGINE), trustEngine);
    Assert.assertSame(context.getAttribute(CONTEXT_KEY_CRITERIA_SET), criteriaSet);
    Assert.assertSame(context.getAttribute(CONTEXT_KEY_TLS_PROTOCOLS), protocols);
    Assert.assertSame(context.getAttribute(CONTEXT_KEY_TLS_CIPHER_SUITES), cipherSuites);
    Assert.assertSame(context.getAttribute(CONTEXT_KEY_CLIENT_TLS_CREDENTIAL), clientTLSCred);
    Assert.assertSame(context.getAttribute(CONTEXT_KEY_HOSTNAME_VERIFIER), verifier);
}

From source file:org.apache.http.client.protocol.RequestAuthCache.java

public void process(final HttpRequest request, final HttpContext context) throws HttpException, IOException {
    Args.notNull(request, "HTTP request");
    Args.notNull(context, "HTTP context");

    final HttpClientContext clientContext = HttpClientContext.adapt(context);

    final AuthCache authCache = clientContext.getAuthCache();
    if (authCache == null) {
        this.log.debug("Auth cache not set in the context");
        return;//from w  w  w  . jav  a 2  s .c o  m
    }

    final CredentialsProvider credsProvider = clientContext.getCredentialsProvider();
    if (credsProvider == null) {
        this.log.debug("Credentials provider not set in the context");
        return;
    }

    final RouteInfo route = clientContext.getHttpRoute();
    HttpHost target = clientContext.getTargetHost();
    if (target.getPort() < 0) {
        target = new HttpHost(target.getHostName(), route.getTargetHost().getPort(), target.getSchemeName());
    }

    final AuthState targetState = clientContext.getTargetAuthState();
    if (targetState != null && targetState.getState() == AuthProtocolState.UNCHALLENGED) {
        final AuthScheme authScheme = authCache.get(target);
        if (authScheme != null) {
            doPreemptiveAuth(target, authScheme, targetState, credsProvider);
        }
    }

    final HttpHost proxy = route.getProxyHost();
    final AuthState proxyState = clientContext.getProxyAuthState();
    if (proxy != null && proxyState != null && proxyState.getState() == AuthProtocolState.UNCHALLENGED) {
        final AuthScheme authScheme = authCache.get(proxy);
        if (authScheme != null) {
            doPreemptiveAuth(proxy, authScheme, proxyState, credsProvider);
        }
    }
}

From source file:org.apache.http.impl.client.AuthenticationStrategyImpl.java

public Queue<AuthOption> select(final Map<String, Header> challenges, final HttpHost authhost,
        final HttpResponse response, final HttpContext context) throws MalformedChallengeException {
    Args.notNull(challenges, "Map of auth challenges");
    Args.notNull(authhost, "Host");
    Args.notNull(response, "HTTP response");
    Args.notNull(context, "HTTP context");
    final HttpClientContext clientContext = HttpClientContext.adapt(context);

    final Queue<AuthOption> options = new LinkedList<AuthOption>();
    final Lookup<AuthSchemeProvider> registry = clientContext.getAuthSchemeRegistry();
    if (registry == null) {
        this.log.debug("Auth scheme registry not set in the context");
        return options;
    }//w w w. j  a v a  2  s .c om
    final CredentialsProvider credsProvider = clientContext.getCredentialsProvider();
    if (credsProvider == null) {
        this.log.debug("Credentials provider not set in the context");
        return options;
    }
    final RequestConfig config = clientContext.getRequestConfig();
    Collection<String> authPrefs = getPreferredAuthSchemes(config);
    if (authPrefs == null) {
        authPrefs = DEFAULT_SCHEME_PRIORITY;
    }
    if (this.log.isDebugEnabled()) {
        this.log.debug("Authentication schemes in the order of preference: " + authPrefs);
    }

    for (final String id : authPrefs) {
        final Header challenge = challenges.get(id.toLowerCase(Locale.US));
        if (challenge != null) {
            final AuthSchemeProvider authSchemeProvider = registry.lookup(id);
            if (authSchemeProvider == null) {
                if (this.log.isWarnEnabled()) {
                    this.log.warn("Authentication scheme " + id + " not supported");
                    // Try again
                }
                continue;
            }
            final AuthScheme authScheme = authSchemeProvider.create(context);
            authScheme.processChallenge(challenge);

            final AuthScope authScope = new AuthScope(authhost.getHostName(), authhost.getPort(),
                    authScheme.getRealm(), authScheme.getSchemeName());

            final Credentials credentials = credsProvider.getCredentials(authScope);
            if (credentials != null) {
                options.add(new AuthOption(authScheme, credentials));
            }
        } else {
            if (this.log.isDebugEnabled()) {
                this.log.debug("Challenge for " + id + " authentication scheme not available");
                // Try again
            }
        }
    }
    return options;
}