/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2011-2015 ForgeRock AS. * * The contents of this file are subject to the terms * of the Common Development and Distribution License * (the License). You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://forgerock.org/license/CDDLv1.0.html * See the License for the specific language governing * permission and limitations under the License. * * When distributing Covered Code, include this CDDL * Header Notice in each file and include the License file * at http://forgerock.org/license/CDDLv1.0.html * If applicable, add the following below the CDDL Header, * with the fields enclosed by brackets [] replaced by * your own identifying information: * "Portions Copyrighted [year] [name of copyright owner]" */ package org.forgerock.openidm.shell.felixgogo.debug; import static org.forgerock.json.JsonValue.json; import static org.forgerock.json.JsonValue.object; import java.io.File; import java.io.IOException; import java.io.StringWriter; import java.util.HashMap; import java.util.Map; import java.util.Scanner; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.felix.service.command.CommandSession; import org.forgerock.json.JsonValue; import org.forgerock.json.resource.ConnectionFactory; import org.forgerock.json.resource.ResourceException; import org.osgi.framework.BundleContext; import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceEvent; import org.osgi.framework.ServiceListener; import org.osgi.framework.ServiceReference; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * A ServiceListener. */ class InteractiveObjectSetService implements /* RequestHandler, */ServiceListener { private final static Logger TRACE = LoggerFactory.getLogger(InteractiveObjectSetService.class); public static final String ROUTER_SERVICE_FILTER = "(service.pid=org.forgerock.openidm.router)"; private ConnectionFactory router = null; private CommandSession session; private final ObjectMapper mapper = new ObjectMapper(); private final BundleContext context; private final Thread parent; public InteractiveObjectSetService(final Thread parent, BundleContext context, CommandSession session) { this.parent = parent; this.context = context; this.session = session; try { ServiceReference<?>[] ref = context.getServiceReferences(ConnectionFactory.class.getName(), ROUTER_SERVICE_FILTER); if (null != ref && ref.length > 0) { router = (ConnectionFactory) context.getService(ref[0]); } } catch (InvalidSyntaxException e) { // couldn't attach router } } /** * {@inheritDoc} */ public JsonValue handle(JsonValue request) throws ResourceException { synchronized (this) { session.getConsole().println("Incoming request:"); if (null == request) { session.getConsole().println("null"); } else { try { StringWriter wr = new StringWriter(); mapper.writerWithDefaultPrettyPrinter().writeValue(wr, request.getObject()); session.getConsole().println(wr.toString()); } catch (IOException e) { session.getConsole().append("Input object serialization exception: ").println( e.getMessage()); } } JsonValue response = null; Scanner input = new Scanner(session.getKeyboard()); do { switch (printInputHelp(input)) { case 1: if (null != router) { return redirect(request, input); } else { session.getConsole().println( "Router is not available, please select something else."); } break; case 2: break; case 3: response = loadFromConsole(input); break; case 4: return null; case 5: printExceptionHelp(input); break; case 6: parent.interrupt(); return new JsonValue(new HashMap<String, Object>()); default: session.getConsole().println("Your should select something [1..6]"); } } while (null == response); return response; } } private ConnectionFactory getRouter() { return router; } private int printInputHelp(Scanner input) { session.getConsole().println("Chose one from the following option and type in the number:"); session.getConsole().println("1: Redirect to a router call"); session.getConsole().println("2: Read response from file"); session.getConsole().println("3: Read response from console"); session.getConsole().println("4: Return null"); session.getConsole().println("5: Throw JsonResourceException"); session.getConsole().println("6: Exit and shutdown the service"); return input.nextInt(); } private JsonValue redirect(JsonValue request, Scanner input) throws ResourceException { session.getConsole().append("Current id: ").println(request.get("id").asString()); session.getConsole().print("Type in the new id: "); String id = input.next(); request.put("id", id); return null; // getRouter().handle(request); } private JsonValue readFile(File inputFile) throws Exception { try { if (inputFile.exists()) { Object map = mapper.readValue(inputFile, Map.class); return new JsonValue(map); } } catch (Exception e) { session.getConsole().format("Error reading file: %s. Exception: %s", inputFile.getAbsolutePath(), e.getMessage()); } return json(object()); } private JsonValue loadFromConsole(Scanner scanner) { session.getConsole().println(); session.getConsole().println("> Press ctrl-D to finish input"); session.getConsole().println("Start data input:"); String input = null; StringBuilder stringBuilder = new StringBuilder(); while (scanner.hasNext()) { input = scanner.next(); if (null == input) { // control-D pressed break; } else { stringBuilder.append(input); } } try { Object map = mapper.readValue(stringBuilder.toString(), Map.class); return new JsonValue(map); } catch (IOException e) { session.getConsole().append("[Exception] Failed to read input from console. Reason: ") .println(e); return null; } } private void printExceptionHelp(Scanner scanner) throws ResourceException { session.getConsole().println("Throw a JsonResourceException"); session.getConsole().print("Type in the numeric code of the exception: "); throw ResourceException.getException(scanner.nextInt(), "Test exception"); } @Override public void serviceChanged(ServiceEvent event) { ServiceReference<?> sr = event.getServiceReference(); switch (event.getType()) { case ServiceEvent.REGISTERED: { router = (ConnectionFactory) context.getService(sr); break; } case ServiceEvent.MODIFIED: { router = (ConnectionFactory) context.getService(sr); break; } case ServiceEvent.UNREGISTERING: { router = null; break; } default: break; } } }