I've read about how HttpClient's LocalTestServer can be used for automated testing, however I can't seem to find where it's been moved. I tried defining dependency to httpclient with tests classifier:
'org.apache.httpcomponents:httpclient:4.5.2:tests'
but there doesn't seem to be a LocalTestServer class defined in there. Has this been discontinued?
Your test should now extend org.apache.http.localserver.LocalServerTestBase.
This is available in the httpclient module with classifier tests.
Your pom could look like:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
<scope>test</scope>
<classifier>tests</classifier>
</dependency>
Related issue:
https://issues.apache.org/jira/browse/HTTPCLIENT-1172
Related changeset:
https://github.com/apache/httpclient/commit/2ebd8202849c1f4a17d4320543e315a46cbfdc10
Can use simple implementation of the LocalServer
public class LocalHttpServer extends ExternalResource {
private static final Logger log = LoggerFactory.getLogger(LocalHttpServer.class);
private final int port;
private MockServer server;
public LocalHttpServer(int port) {
this.port = port;
}
#Override
protected void before() throws Throwable {
server = new MockServer();
server.setUp();
}
public void start() throws Exception {
server.start(port);
log.info("LocalHttpServer started on {}", port);
}
/**
* Need to be setup before starting server
*/
public LocalHttpServer registerSimpleHandler(String path, String resp) {
server.registerSimpleHandler(path, resp);
return this;
}
#Override
protected void after() {
try {
server.shutDown();
} catch (Exception e) {
e.printStackTrace();
}
log.info("LocalHttpServer shutdown on {}", port);
}
static class MockServer extends LocalServerTestBase {
#Override
public void setUp() throws Exception {
super.setUp();
HttpRequestFactory requestFactory = new DefaultHttpRequestFactory() {
#Override
public HttpRequest newHttpRequest(final RequestLine requestline) throws MethodNotSupportedException {
return super.newHttpRequest(requestline);
}
};
HttpMessageParserFactory<HttpRequest> requestParserFactory = new DefaultHttpRequestParserFactory(
BasicLineParser.INSTANCE, requestFactory);
DefaultBHttpServerConnectionFactory connectionFactory = new DefaultBHttpServerConnectionFactory(
ConnectionConfig.DEFAULT, requestParserFactory, DefaultHttpResponseWriterFactory.INSTANCE);
this.serverBootstrap.setConnectionFactory(connectionFactory);
}
public void registerSimpleHandler(String path, String resp) {
this.serverBootstrap.registerHandler(path, (request, response, context) ->
response.setEntity(new StringEntity(resp, ContentType.TEXT_PLAIN)));
}
public void start(int port) throws Exception {
this.serverBootstrap.setListenerPort(port);
start();
}
}
Example usage
public class HttpTest {
private static final LocalHttpServer LOCAL_HTTP = new LocalHttpServer(8080);
#ClassRule
public static final RuleChain RULE_CHAIN = RuleChain.outerRule(LOCAL_HTTP);
#Before
public void setUp() throws Exception {
LOCAL_HTTP.registerSimpleHandler("/path", "response")
.start();
}
#Test
public void someTest() {
//request here
}
}
Related
here is my code, AgentRest is not mocked in A class
class A {
public void t() throws IOException {
AgentRest agentRest = new AgentRest("127.0.0.1", 8888);
HttpResponse<TaskStatusResponse> a = agentRest.dataBackup(null); // not mock
}
}
#Slf4j
#PrepareForTest({A.class, SftpClientTest.class,AgentRest.class })
#RunWith(PowerMockRunner.class)
class SftpClientTest {
#Test
void getHome() throws Exception {
HttpResponse<TaskStatusResponse> httpResponse =
HttpResponse.<TaskStatusResponse>builder().code(0).body(TaskStatusResponse.builder().status("").build()).build();
AgentRest agentRest = PowerMockito.mock(AgentRest.class);
PowerMockito.whenNew(AgentRest.class).withAnyArguments().thenReturn(agentRest);
PowerMockito.when(agentRest.dataBackup(ArgumentMatchers.any())).thenReturn(httpResponse);
new A().t();
log.info("");
}
}
i have try a lot but still failed, PowerMockito.whenNew seams not working, and i have added all class to PrepareForTest
I have found the probelm is junit5 is not working with powermock, solution link: https://rieckpil.de/mock-java-constructors-and-their-object-creation-with-mockito/
here is my new code:
class A {
public void t() throws IOException {
AgentRest agentRest = new AgentRest("127.0.0.1", 8888);
HttpResponse<TaskStatusResponse> a = agentRest.dataBackup(null);
}
}
#Slf4j
class SftpClientTest {
#Test
void getHome() throws Exception {
try (MockedConstruction<AgentRest> mocked = mockConstruction(AgentRest.class)) {
HttpResponse<TaskStatusResponse> httpResponse =
HttpResponse.<TaskStatusResponse>builder().code(0).body(TaskStatusResponse.builder().status("").build()).build();
// every object creation is returning a mock from now on
AgentRest agentRest = new AgentRest("sa", 22);
when(agentRest.dataBackup(ArgumentMatchers.any())).thenReturn(httpResponse);
new A().t();
}
}
}
I want to send multiple outbound message with my own custom JCA outbound adapter on Liberty application server .
this is my resource adapter :
#Connector(description = "Example Resource Adapter", displayName = "Example Resource Adapter", eisType = "Example Resource Adapter", version = "1.0")
public class ExampleResourceAdapter implements ResourceAdapter {
private EndpointTarget endpointTarget;
private MessageEndpointFactory messageEndpointFactory;
public void start(BootstrapContext bootstrapContext) {
}
public void stop() {
}
public void endpointActivation(final MessageEndpointFactory messageEndpointFactory, final ActivationSpec activationSpec) {
this.messageEndpointFactory = messageEndpointFactory;
}
public void endpointDeactivation(MessageEndpointFactory messageEndpointFactory, ActivationSpec activationSpec) {
if (endpointTarget != null) {
endpointTarget.getMessageEndpoint().release();
}
}
public XAResource[] getXAResources(ActivationSpec[] activationSpecs) {
return new XAResource[0];
}
public void executeRequest(String iid) {
endpointTarget = new EndpointTarget(messageEndpointFactory, iid);
endpointTarget.start();
}
and this is jca managed connection :
public class ExampleManagedConnection implements ManagedConnection {
private static Logger log = Logger.getLogger(ExampleManagedConnection.class.getName());
private PrintWriter logwriter;
private ExampleManagedConnectionFactory mcf;
private List<ConnectionEventListener> listeners;
private ExampleConnectionImpl connection;
public ExampleManagedConnection(ExampleManagedConnectionFactory mcf) {
this.mcf = mcf;
this.logwriter = null;
this.listeners = Collections.synchronizedList(new ArrayList<>(1));
this.connection = null;
}
public Object getConnection(Subject subject,
ConnectionRequestInfo cxRequestInfo) throws ResourceException {
log.finest("getConnection()");
connection = new ExampleConnectionImpl(this, mcf);
return connection;
}
public void associateConnection(Object connection) throws ResourceException {
log.finest("associateConnection()");
if (connection == null)
throw new ResourceException("Null connection handle");
if (!(connection instanceof ExampleConnectionImpl))
throw new ResourceException("Wrong connection handle");
this.connection = (ExampleConnectionImpl) connection;
}
public void cleanup() throws ResourceException {
log.finest("cleanup()");
}
public void destroy() throws ResourceException {
log.finest("destroy()");
}
public void addConnectionEventListener(ConnectionEventListener listener) {
log.finest("addConnectionEventListener()");
if (listener == null) {
throw new IllegalArgumentException("Listener is null");
}
listeners.add(listener);
}
public void removeConnectionEventListener(ConnectionEventListener listener) {
log.finest("removeConnectionEventListener()");
if (listener == null)
throw new IllegalArgumentException("Listener is null");
listeners.remove(listener);
}
public PrintWriter getLogWriter() throws ResourceException {
log.finest("getLogWriter()");
return logwriter;
}
public void setLogWriter(PrintWriter out) throws ResourceException {
log.finest("setLogWriter()");
logwriter = out;
}
public LocalTransaction getLocalTransaction() throws ResourceException {
throw new NotSupportedException("getLocalTransaction() not supported");
}
public XAResource getXAResource() throws ResourceException {
throw new NotSupportedException("getXAResource() not supported");
}
public ManagedConnectionMetaData getMetaData() throws ResourceException {
log.finest("getMetaData()");
return new ExampleManagedConnectionMetaData();
}
public void getPreTimeMarketOrders(String iid) {
ExampleResourceAdapter ExampleResourceAdapter = (ExampleResourceAdapter) mcf.getResourceAdapter();
ExampleResourceAdapter.executeRequest(iid);
}
}
i receive this exception when send more than 500 requests :
javax.resource.spi.RetryableUnavailableException: limit for number of MessageEndpoint proxies reached. Limit = 500
at com.ibm.ws.ejbcontainer.mdb.BaseMessageEndpointFactory.createEndpoint(BaseMessageEndpointFactory.java:349)
at com.ibm.ws.ejbcontainer.mdb.internal.MessageEndpointFactoryImpl.createEndpoint(MessageEndpointFactoryImpl.java:385)
How can change JCA adapter Thread Pool in Liberty/OpenLiberty Application Server ?
Looking at the OpenLiberty source, 500 is a default value that is used absent other configuration.
It looks like you can configure a different max pool size for a bean type. Refer to the section covering com.ibm.websphere.ejbcontainer.poolSize in this document.
That said, your approach seems a bit unconventional in that MessageEndpointFactory is intended for inbound, not outbound communication. Inbound communication involves a Message Driven Bean to receive the inbound messages (which could have a com.ibm.websphere.ejbcontainer.poolSize configured for it).
Your approach of overwriting endpointTarget within executeRequest is also suspicious. #Connector/ResourceAdapter class ExampleResourceAdapter is a singleton, so if you have overlapping executeRequest it will overwrite endpointTarget and only one of them will be released in endpointDeactivation.
I want to develop notification sender in real time with Spring Boot but I can't use Stomp and sockjs, so I need implement raw WebSocket but I can't find out how to set Principal in WebSocket connection beacuse I want to Authenticate with JWT token. So, where or how can I set principal.
I'am using these;
WebSocketConfig.java :
#EnableWebSocket
#Configuration
public class WebSocketConfig implements WebSocketConfigurer {
#Autowired
WebSocketNotificationSenderService senderService;
#Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry
webSocketHandlerRegistry) {
webSocketHandlerRegistry.addHandler(createHandler(),
"/handler").addInterceptors(new HttpSessionHandshakeInterceptor()
{
#Override
public void afterHandshake(ServerHttpRequest request,
ServerHttpResponse response, WebSocketHandler wsHandler,
#Nullable Exception ex) {
super.afterHandshake(request, response, wsHandler, ex);
}
#Override
public boolean beforeHandshake(ServerHttpRequest request,
ServerHttpResponse response, WebSocketHandler wsHandler,
Map<String, Object> attributes) throws Exception {
return super.beforeHandshake(request, response,
wsHandler, attributes)
}
});
}
#Bean
public WebSocketHandler createHandler() {
return new MyHandler(senderService);
}
}
MyHandler.java :
#Component
public class MyHandler extends TextWebSocketHandler {
WebSocketNotificationSenderService senderService;
public MyHandler(WebSocketNotificationSenderService senderService){
this.senderService = senderService;
}
#Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
senderService.addToSession(session);
}
}
WebSocketNotificationSenderService.java :
#Service
public class WebSocketNotificationSenderService implements
IWebSocketSenderService<WrapperWsNotification> {
private List<WebSocketSession> sessions = new CopyOnWriteArrayList<>();
private ObjectMapper mapper = new ObjectMapper();
public void addToSession(WebSocketSession session) {
sessions.add(session);
}
#Override
public void convertAndSend(WrapperWsNotification payload) throws JsonProcessingException {
String payloadString = mapper.writeValueAsString(payload);
sessions.stream().forEach(session -> {
try {
session.sendMessage(new TextMessage(payloadString));
} catch (IOException e) {
e.printStackTrace();
}
});
}
#Override
public void convertAndSendToUser(String user, WrapperWsNotification payload) throws
JsonProcessingException {
String payloadString = mapper.writeValueAsString(payload);
sessions.forEach(session -> {
if (session.getPrincipal().getName().equals(user)) {
try {
session.sendMessage(new TextMessage(payloadString));
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
}
My Notification Sender to websocket;
#Component
public class NotificationConsumer {
#Autowired
WebSocketNotificationSenderService webSocket;
private Logger logger = LoggerFactory.getLogger(NotificationConsumer.class);
public void onReceiveNotification(String object) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
WrapperWsNotification wrapperWsNotification= objectMapper.readValue(object, WrapperWsNotification.class);
logger.info("User where coming from redis " + wrapperWsNotification.getUser().getUsername());
webSocket.convertAndSendToUser(wrapperWsNotification.getUser().getUsername(), wrapperWsNotification);
}
}
I find out solution and added an example
This is a part of my class, I want to test:
public class PrefPanel extends Composite {
private static PrefPanelUiBinder uiBinder = GWT.create(PrefPanelUiBinder.class);
interface PrefPanelUiBinder extends UiBinder<Widget, PrefPanel> {}
public PrefPanel(GlobalParams globalParams) {
initWidget(uiBinder.createAndBindUi(this));
String url = URL.encode(globalParams.getBaseUrl() + "book.html");
RequestBuilder builder = new RequestBuilder(RequestBuilder.POST, url);
try {
Request response = builder.sendRequest(jsonString, new RequestCallback() {
#Override
public void onError(Request request, Throwable exception) {
displayError("Error");
}
#Override
public void onResponseReceived(Request request, Response response) {
updateBookList(response.getText());
}
});
} catch (RequestException e) {
displayError("Error");
}
Here is a part of my test class:
#RunWith(GwtMockitoTestRunner.class)
public class PositionServiceTest {
#Mock RequestBuilder builder;
#Mock GlobalParams globalParams;
#Mock URL url;
private PrefPanel prefPanel;
#Before
public void setup() {
GwtMockito.useProviderForType(RequestBuilder.class, new FakeProvider() {
#Override
public Object getFake(Class aclass) {
return builder;
}
});
when(globalParams.getBaseUrl()).thenReturn("http://localhost/");
prefPanel = new PrefPanel(globalParams);
...
When I start to debug I get an error message:
- url cannot be empty
- java.lang.IllegalArgumentException
- at com.google.gwt.http.client.StringValidator.throwlfEmptyOrNull(StringValidator.java:52)
- ...
The error occurs on the line where I create the RequestBuilder (new RequestBuilder). I have no idea how to create a new instance of RequestBuilder. Could you give me a clue?
I have heard that gwtmockit can't handle constructors. Is there a way to avoid the new RequestBuilder? Do I have to use powermockito?
The code given below works fine when I send manual requests. If I generate requests with siege (siege -c 500 -r 100 'http://localhost:8080/?name=Chandru&age=560'), I start seeing these messages in jetty's log:
2013-01-02 00:06:55.761:WARN:oejh.HttpGenerator:Ignoring extra content {name: "
2013-01-02 00:07:56.393:WARN:oejh.HttpGenerator:Ignoring extra content Chandru
2013-01-02 00:07:56.393:WARN:oejh.HttpGenerator:Ignoring extra content ", age:
2013-01-02 00:07:56.393:WARN:oejh.HttpGenerator:Ignoring extra content 560
2013-01-02 00:07:56.393:WARN:oejh.HttpGenerator:Ignoring extra content }
I'm using Jetty 8.1.8.v20121106 on Java 1.7.0_10.What am I doing wrong?
public class Main {
public static void main(String[] args) throws Exception {
final Server server = new Server(8080);
final ServletContextHandler context = new ServletContextHandler(server, "/");
final ServletHolder servlet = new ServletHolder(new RequestHandler(new Responder()));
servlet.setAsyncSupported(true);
context.addServlet(servlet, "/");
server.start();
}
}
class RequestHandler extends HttpServlet {
private final Responder responder;
public RosterHandler(Responder responder) {
this.responder = responder;
}
#Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
responder.process(request.startAsync());
}
}
class Responder {
private final ExecutorService pool;
public Responder() {
this.pool = Executors.newFixedThreadPool(100);
}
public void process(final AsyncContext ctx) {
pool.execute(new Runnable() {
#Override
public void run() {
final String name = ctx.getRequest().getParameter("name");
final int age = Integer.parseInt(ctx.getRequest().getParameter("age"));
ctx.getResponse().setContentType("application/json");
try (final PrintWriter w = ctx.getResponse().getWriter()) {
w.printf("{name: \"%s\", age: %d}", name, age);
} catch (IOException e) {
e.printStackTrace(System.err);
}
}
});
}
}
You should call context.complete() to signal that your work is done and the async connection can be considered finished.