Search in sources :

Example 6 with CachedCommandModel

use of com.sun.enterprise.admin.util.CachedCommandModel in project Payara by payara.

the class AdminCacheUtilsTest method testGetProvider4CommandModel.

@Test
public void testGetProvider4CommandModel() throws Exception {
    DataProvider provider;
    byte[] data;
    assertNotNull(provider = acu.getProvider(CommandModel.class));
    CachedCommandModel beatles1 = CachedCommandModelTest.createBeateles();
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    provider.writeToStream(beatles1, baos);
    assertNotNull(data = baos.toByteArray());
    System.out.println("BTW: " + new String(data, "UTF-8"));
    CachedCommandModel beatles2 = (CachedCommandModel) provider.toInstance(new ByteArrayInputStream(data), CachedCommandModel.class);
    beatles2.setETag(null);
    assertEquals(beatles1.getETag(), CachedCommandModel.computeETag(beatles2));
}
Also used : ByteArrayInputStream(java.io.ByteArrayInputStream) CachedCommandModel(com.sun.enterprise.admin.util.CachedCommandModel) ByteArrayOutputStream(java.io.ByteArrayOutputStream) Test(org.junit.Test) CachedCommandModelTest(com.sun.enterprise.admin.util.CachedCommandModelTest)

Example 7 with CachedCommandModel

use of com.sun.enterprise.admin.util.CachedCommandModel in project Payara by payara.

the class RemoteAdminCommand method doHttpCommand.

/**
 * Set up an HTTP connection, call cmd.prepareConnection so the consumer of
 * the connection can further configure it, then open the connection (following
 * redirects if needed), then call cmd.useConnection so the consumer of the
 * connection can use it.
 * <P>
 * This method will try to execute the command repeatedly, for example,
 * retrying with updated credentials (typically from the interactive user), etc., until the
 * command succeeds or there are no more ways to retry that might succeed.
 *
 * @param uriString     the URI to connect to
 * @param httpMethod    the HTTP method to use for the connection
 * @param cmd           the HttpCommand object
 * @throws CommandException if anything goes wrong
 */
private void doHttpCommand(String uriString, String httpMethod, HttpCommand cmd, boolean isForMetadata) throws CommandException {
    HttpURLConnection urlConnection;
    /*
         * There are various reasons we might retry the command - an authentication
         * challenges from the DAS, shifting from an insecure connection to
         * a secure one, etc.  So just keep trying as long as it makes sense.
         *
         * Any exception handling code inside the loop that changes something
         * about the connection or the request and wants to retry must set
         * shoudTryCommandAgain to true.
         */
    boolean shouldTryCommandAgain;
    /*
         * If the DAS challenges us for credentials and we've already sent
         * the caller-provided ones, we might ask the user for a new set
         * and use them.  But we want to ask only once.
         */
    boolean askedUserForCredentials = false;
    /*
         * On a subsequent retry we might need to use secure, even if the
         * caller did not request it.
         */
    boolean shouldUseSecure = secure;
    /*
         * Send the caller-provided credentials (typically from command line
         * options or the password file) on the first attempt only if we know
         * the connection will
         * be secure.
         */
    boolean usedCallerProvidedCredentials = secure;
    /*
         * Note: HttpConnectorAddress will set up SSL/TLS client cert
         * handling if the current configuration calls for it.
         */
    HttpConnectorAddress url = getHttpConnectorAddress(host, port, shouldUseSecure);
    url.setInteractive(interactive);
    do {
        /*
             * Any code that wants to trigger a retry will say so explicitly.
             */
        shouldTryCommandAgain = false;
        try {
            if (logger.isLoggable(Level.FINER)) {
                logger.log(Level.FINER, "URI: {0}", uriString);
                logger.log(Level.FINER, "URL: {0}", url.toString());
                logger.log(Level.FINER, "URL: {0}", url.toURL(uriString).toString());
                logger.log(Level.FINER, "Password options: {0}", passwordOptions);
                logger.log(Level.FINER, "Using auth info: User: {0}, Password: {1}", new Object[] { user, (password != null && password.length > 0) ? "<non-null>" : "<null>" });
            }
            final AuthenticationInfo authInfo = authenticationInfo();
            if (authInfo != null) {
                url.setAuthenticationInfo(authInfo);
            }
            urlConnection = (HttpURLConnection) url.openConnection(uriString);
            urlConnection.setRequestProperty("User-Agent", responseFormatType);
            if (passwordOptions != null) {
                urlConnection.setRequestProperty("X-passwords", passwordOptions.toString());
            }
            if (authToken != null) {
                /*
                     * If this request is for metadata then we expect to reuse
                     * the auth token.   
                     */
                urlConnection.setRequestProperty(SecureAdmin.Util.ADMIN_ONE_TIME_AUTH_TOKEN_HEADER_NAME, (isForMetadata ? AuthTokenManager.markTokenForReuse(authToken) : authToken));
            }
            if (commandModel != null && isCommandModelFromCache() && commandModel instanceof CachedCommandModel) {
                urlConnection.setRequestProperty(COMMAND_MODEL_MATCH_HEADER, ((CachedCommandModel) commandModel).getETag());
                if (logger.isLoggable(Level.FINER)) {
                    logger.log(Level.FINER, "CommandModel ETag: {0}", ((CachedCommandModel) commandModel).getETag());
                }
            }
            urlConnection.setRequestMethod(httpMethod);
            urlConnection.setReadTimeout(readTimeout);
            if (connectTimeout >= 0)
                urlConnection.setConnectTimeout(connectTimeout);
            addAdditionalHeaders(urlConnection);
            cmd.prepareConnection(urlConnection);
            urlConnection.connect();
            /*
                 * We must handle redirection from http to https explicitly
                 * because, even if the HttpURLConnection's followRedirect is
                 * set to true, the Java SE implementation does not do so if the
                 * procotols are different.
                 */
            String redirection = checkConnect(urlConnection);
            if (redirection != null) {
                /*
                     * Log at FINER; at FINE it would appear routinely when used from
                     * asadmin.
                     */
                logger.log(Level.FINER, "Following redirection to " + redirection);
                url = followRedirection(url, redirection);
                shouldTryCommandAgain = true;
                /*
                     * Record that, during the retry of this request, we should
                     * use https.
                     */
                shouldUseSecure = url.isSecure();
                /*
                     * Record that, if this is a metadata request, the real
                     * request should use https also.
                     */
                secure = true;
                urlConnection.disconnect();
                continue;
            }
            /*
                 * No redirection, so we have established the connection.
                 * Now delegate again to the command processing to use the
                 * now-created connection.
                 */
            cmd.useConnection(urlConnection);
            processHeaders(urlConnection);
            logger.finer("doHttpCommand succeeds");
        } catch (AuthenticationException authEx) {
            logger.log(Level.FINER, "DAS has challenged for credentials");
            /*
                 * The DAS has challenged us to provide valid credentials.
                 *
                 * We might have sent the request without credentials previously
                 * (because the connection was not secure, typically). In that case,
                 * retry using the caller provided credentials (if there are any).
                 */
            if (!usedCallerProvidedCredentials) {
                logger.log(Level.FINER, "Have not tried caller-supplied credentials yet; will do that next");
                usedCallerProvidedCredentials = true;
                shouldTryCommandAgain = true;
                continue;
            }
            /*
                 * We already tried the caller-provided credentials.  Try to
                 * update the credentials if we haven't already done so.
                 */
            logger.log(Level.FINER, "Already used caller-supplied credentials");
            if (askedUserForCredentials) {
                /*
                     * We already updated the credentials once, and the updated
                     * ones did not work.  No recourse.
                     */
                logger.log(Level.FINER, "Already tried with updated credentials; cannot authenticate");
                throw authEx;
            }
            /*
                 * Try to update the creds.
                 */
            logger.log(Level.FINER, "Have not yet tried to update credentials, so will try to update them");
            if (!updateAuthentication()) {
                /*
                     * No updated credentials are avaiable, so we
                     * have no more options.
                     */
                logger.log(Level.FINER, "Could not update credentials; cannot authenticate");
                throw authEx;
            }
            /*
                 * We have another set of credentials we can try.
                 */
            logger.log(Level.FINER, "Was able to update the credentials so will retry with the updated ones");
            askedUserForCredentials = true;
            shouldTryCommandAgain = true;
            continue;
        } catch (ConnectException ce) {
            logger.finer("doHttpCommand: connect exception " + ce);
            // this really means nobody was listening on the remote server
            // note: ConnectException extends IOException and tells us more!
            String msg = strings.get("ConnectException", host, port + "");
            throw new CommandException(msg, ce);
        } catch (UnknownHostException he) {
            logger.finer("doHttpCommand: host exception " + he);
            // bad host name
            String msg = strings.get("UnknownHostException", host);
            throw new CommandException(msg, he);
        } catch (SocketException se) {
            logger.finer("doHttpCommand: socket exception " + se);
            try {
                boolean serverAppearsSecure = NetUtils.isSecurePort(host, port);
                if (serverAppearsSecure && !shouldUseSecure) {
                    if (retryUsingSecureConnection(host, port)) {
                        // retry using secure connection
                        shouldUseSecure = true;
                        usedCallerProvidedCredentials = true;
                        shouldTryCommandAgain = true;
                        continue;
                    }
                }
                throw new CommandException(se);
            } catch (IOException io) {
                // XXX - logger.printExceptionStackTrace(io);
                throw new CommandException(io);
            }
        } catch (SSLException se) {
            logger.finer("doHttpCommand: SSL exception " + se);
            try {
                boolean serverAppearsSecure = NetUtils.isSecurePort(host, port);
                if (!serverAppearsSecure && secure) {
                    logger.log(Level.SEVERE, AdminLoggerInfo.mServerIsNotSecure, new Object[] { host, port });
                }
                throw new CommandException(se);
            } catch (IOException io) {
                // XXX - logger.printExceptionStackTrace(io);
                throw new CommandException(io);
            }
        } catch (SocketTimeoutException e) {
            logger.finer("doHttpCommand: read timeout " + e);
            throw new CommandException(strings.get("ReadTimeout", (float) readTimeout / 1000), e);
        } catch (IOException e) {
            logger.finer("doHttpCommand: IO exception " + e);
            throw new CommandException(strings.get("IOError", e.getMessage()), e);
        } catch (CommandException e) {
            throw e;
        } catch (Exception e) {
            // logger.log(Level.FINER, "doHttpCommand: exception", e);
            logger.finer("doHttpCommand: exception " + e);
            ByteArrayOutputStream buf = new ByteArrayOutputStream();
            e.printStackTrace(new PrintStream(buf));
            logger.finer(buf.toString());
            throw new CommandException(e);
        }
    } while (shouldTryCommandAgain);
    // no longer needed
    outboundPayload = null;
}
Also used : SocketException(java.net.SocketException) PrintStream(java.io.PrintStream) UnknownHostException(java.net.UnknownHostException) AuthenticationException(org.glassfish.api.admin.AuthenticationException) CachedCommandModel(com.sun.enterprise.admin.util.CachedCommandModel) InvalidCommandException(org.glassfish.api.admin.InvalidCommandException) CommandException(org.glassfish.api.admin.CommandException) IOException(java.io.IOException) ByteArrayOutputStream(java.io.ByteArrayOutputStream) SSLException(javax.net.ssl.SSLException) AuthenticationInfo(com.sun.enterprise.admin.util.AuthenticationInfo) FileNotFoundException(java.io.FileNotFoundException) CommandValidationException(org.glassfish.api.admin.CommandValidationException) SSLException(javax.net.ssl.SSLException) SAXException(org.xml.sax.SAXException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) InvalidCommandException(org.glassfish.api.admin.InvalidCommandException) SocketException(java.net.SocketException) SocketTimeoutException(java.net.SocketTimeoutException) CommandException(org.glassfish.api.admin.CommandException) ConnectException(java.net.ConnectException) MalformedURLException(java.net.MalformedURLException) AuthenticationException(org.glassfish.api.admin.AuthenticationException) IOException(java.io.IOException) UnknownHostException(java.net.UnknownHostException) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException) HttpConnectorAddress(com.sun.enterprise.admin.util.HttpConnectorAddress) HttpURLConnection(java.net.HttpURLConnection) SocketTimeoutException(java.net.SocketTimeoutException) ConnectException(java.net.ConnectException)

Example 8 with CachedCommandModel

use of com.sun.enterprise.admin.util.CachedCommandModel in project Payara by payara.

the class RemoteRestAdminCommand method getCommandModelFromCache.

private CommandModel getCommandModelFromCache() {
    String cachedModel = AdminCacheUtils.getCache().get(createCommandCacheKey(), String.class);
    if (cachedModel == null) {
        return null;
    }
    cachedModel = cachedModel.trim();
    int ind = cachedModel.indexOf('\n');
    if (ind < 0) {
        return null;
    }
    String eTag = cachedModel.substring(0, ind);
    if (!eTag.startsWith("ETag:")) {
        return null;
    }
    eTag = eTag.substring(5).trim();
    if (logger.isLoggable(Level.FINEST)) {
        logger.log(Level.FINEST, "Cached command model ETag is {0}", eTag);
    }
    String content = cachedModel.substring(ind + 1).trim();
    CachedCommandModel result = parseMetadata(content, eTag);
    return result;
}
Also used : CachedCommandModel(com.sun.enterprise.admin.util.CachedCommandModel)

Example 9 with CachedCommandModel

use of com.sun.enterprise.admin.util.CachedCommandModel in project Payara by payara.

the class RemoteAdminCommand method parseMetadata.

/**
 * Parse the XML metadata for the command on the input stream.
 *
 * @param in the input stream
 * @return the set of ValidOptions
 */
private CommandModel parseMetadata(InputStream in, StringBuilder errors) {
    if (logger.isLoggable(Level.FINER)) {
        // XXX - assume "debug" == "FINER"
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            FileUtils.copy(in, baos, 0);
        } catch (IOException ex) {
        }
        in = new ByteArrayInputStream(baos.toByteArray());
        String response = baos.toString();
        logger.finer("------- RAW METADATA RESPONSE ---------");
        logger.finer(response);
        logger.finer("------- RAW METADATA RESPONSE ---------");
    }
    CachedCommandModel cm = new CachedCommandModel(name);
    boolean sawFile = false;
    try {
        DocumentBuilder d = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        Document doc = d.parse(in);
        NodeList cmd = doc.getElementsByTagName("command");
        Node cmdnode = cmd.item(0);
        if (cmdnode == null) {
            Node report = doc.getElementsByTagName("action-report").item(0);
            String cause = getAttr(report.getAttributes(), "failure-cause");
            if (ok(cause))
                errors.append(cause);
            else {
                // message-part
                Node mp = report.getFirstChild();
                if (mp != null)
                    cause = getAttr(mp.getAttributes(), "message");
                if (ok(cause))
                    errors.append(cause);
            }
            // wrong with command implementation
            return null;
        }
        NamedNodeMap cmdattrs = cmdnode.getAttributes();
        usage = getAttr(cmdattrs, "usage");
        cm.setUsage(usage);
        String dashOk = getAttr(cmdattrs, "unknown-options-are-operands");
        if (dashOk != null)
            cm.dashOk = Boolean.parseBoolean(dashOk);
        NodeList opts = doc.getElementsByTagName("option");
        for (int i = 0; i < opts.getLength(); i++) {
            Node n = opts.item(i);
            NamedNodeMap attributes = n.getAttributes();
            String sn = getAttr(attributes, "short");
            String def = getAttr(attributes, "default");
            String obs = getAttr(attributes, "obsolete");
            String alias = getAttr(attributes, "alias");
            ParamModelData opt = new ParamModelData(getAttr(attributes, "name"), typeOf(getAttr(attributes, "type")), Boolean.parseBoolean(getAttr(attributes, "optional")), def, ok(sn) ? sn : null, ok(obs) ? Boolean.parseBoolean(obs) : false, alias);
            if (getAttr(attributes, "type").equals("PASSWORD")) {
                opt.param._password = true;
                opt.prompt = getAttr(attributes, "prompt");
                opt.promptAgain = getAttr(attributes, "promptAgain");
            }
            cm.add(opt);
            if (opt.getType() == File.class)
                sawFile = true;
        }
        // should be only one operand item
        opts = doc.getElementsByTagName("operand");
        for (int i = 0; i < opts.getLength(); i++) {
            Node n = opts.item(i);
            NamedNodeMap attributes = n.getAttributes();
            Class<?> type = typeOf(getAttr(attributes, "type"));
            if (type == File.class) {
                sawFile = true;
            }
            int min = Integer.parseInt(getAttr(attributes, "min"));
            String max = getAttr(attributes, "max");
            boolean multiple = false;
            if (max.equals("unlimited")) {
                multiple = true;
                // XXX - should convert to array of whatever
                if (type == File.class) {
                    type = File[].class;
                } else {
                    type = List.class;
                }
            }
            ParamModelData pm = new ParamModelData(getAttr(attributes, "name"), type, min == 0, null);
            pm.param._primary = true;
            pm.param._multiple = multiple;
            cm.add(pm);
        }
        /*
             * If one of the options or operands is a FILE,
             * make sure there's also a --upload option available.
             * XXX - should only add it if it's not present
             * XXX - should just define upload parameter on remote command
             */
        if (sawFile) {
            cm.add(new ParamModelData("upload", Boolean.class, true, null));
            addedUploadOption = true;
            cm.setAddedUploadOption(true);
        }
    } catch (ParserConfigurationException pex) {
        // ignore for now
        return null;
    } catch (SAXException sex) {
        // ignore for now
        return null;
    } catch (IOException ioex) {
        // ignore for now
        return null;
    }
    return cm;
}
Also used : NamedNodeMap(org.w3c.dom.NamedNodeMap) NodeList(org.w3c.dom.NodeList) Node(org.w3c.dom.Node) ParamModelData(com.sun.enterprise.admin.util.CommandModelData.ParamModelData) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) CachedCommandModel(com.sun.enterprise.admin.util.CachedCommandModel) Document(org.w3c.dom.Document) SAXException(org.xml.sax.SAXException) ByteArrayInputStream(java.io.ByteArrayInputStream) DocumentBuilder(javax.xml.parsers.DocumentBuilder) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException) SmartFile(com.sun.enterprise.universal.io.SmartFile) File(java.io.File)

Aggregations

CachedCommandModel (com.sun.enterprise.admin.util.CachedCommandModel)9 ParamModelData (com.sun.enterprise.admin.util.CommandModelData.ParamModelData)4 SSLException (javax.net.ssl.SSLException)4 ByteArrayOutputStream (java.io.ByteArrayOutputStream)3 IOException (java.io.IOException)3 ParserConfigurationException (javax.xml.parsers.ParserConfigurationException)3 SAXException (org.xml.sax.SAXException)3 AuthenticationInfo (com.sun.enterprise.admin.util.AuthenticationInfo)2 HttpConnectorAddress (com.sun.enterprise.admin.util.HttpConnectorAddress)2 SmartFile (com.sun.enterprise.universal.io.SmartFile)2 ByteArrayInputStream (java.io.ByteArrayInputStream)2 FileNotFoundException (java.io.FileNotFoundException)2 UnsupportedEncodingException (java.io.UnsupportedEncodingException)2 ConnectException (java.net.ConnectException)2 MalformedURLException (java.net.MalformedURLException)2 SocketException (java.net.SocketException)2 SocketTimeoutException (java.net.SocketTimeoutException)2 UnknownHostException (java.net.UnknownHostException)2 JsonObject (javax.json.JsonObject)2 AuthenticationException (org.glassfish.api.admin.AuthenticationException)2