Does MaterialModule in Angular Material 2 include Http providers by default?
I have created a service that injects Http from #angular/http. If I omit to import HttpModule in the main AppModule, there is no error and everything works as expected. If on the contrary, I remove the import of MaterialModule, then I get the error that there is no provider for Http.
Since I import the whole MaterialModule, I can see that this is due to the automatic import of MdIconModule. It uses HttpModule internally in order to fetch Material Design icons.
Related
We have a spring boot application with REST interface and a web client. We are using spring-security with OAuth 2.0 JWT tokens for authentication. We are using slf4j and sleuth for logging. We want to log the currently logged-in user id in our logs. Technically, we want to add the user id to the Mapped Diagnostic Context (MDC) of our server application.
The goal is to link server side errors resulting from frontend operations to the user who has triggerend the backend operation.
At the moment, we extract the user id on the client side and send the id as HTTP header field to the server where it is extraced from the HTTP header as baggage by sleuth and added to the logs, see following spring.sleuth.baggage configuration. This is working.
spring.sleuth.baggage.remote-fields=user_id
spring.sleuth.baggage.tag-fields=user_id
spring.sleuth.baggage.correlation-fields=user_id
The user is logged by user=%X{user_id:-}, see the full log pattern:
logging:
level:
ROOT: WARN
pattern:
console: "[%d] [%t] %highlight(%-5p) %c{10} - %cyan([trace=%X{X-B3-TraceId:-} span=%X{X-B3-SpanId:-} user=%X{user_id:-}]) %m%n"
However, instead of extracting the user id on the client side and sending it to the backend, we want to directly extract the user id from the JWT token on the server side. Since all the information are also directly available on the server side.
I have checked spring-cloud-sleuth documentation how to set baggage fields in Java, but I couldn't figure out how to do it.
https://cloud.spring.io/spring-cloud-sleuth/reference/html/#java-configuration
https://docs.spring.io/spring-cloud-sleuth/docs/current-SNAPSHOT/reference/html/project-features.html#features-brave-baggage
https://docs.spring.io/spring-cloud-sleuth/docs/current-SNAPSHOT/reference/html/appendix.html#appendix
I did not know which classes to use and how to use them. I've tried the following code. The code is not executed at Spring startup. So, it seems some config is missing or the code is completely wrong.
package net.company.common.service;
import brave.baggage.BaggageField;
import brave.baggage.BaggagePropagation;
import brave.baggage.BaggagePropagationConfig;
import brave.baggage.BaggagePropagationCustomizer;
import brave.internal.baggage.BaggageContext;
import net.company.common.service.CommonServiceConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
#Configuration
#ComponentScan
#Import({CommonServiceConfig.class})
public class ServiceConfig {
#Bean
BaggagePropagationConfig.SingleBaggageField singleBaggageField() {
BaggagePropagationConfig.SingleBaggageField field = BaggagePropagationConfig.SingleBaggageField.newBuilder(BaggageField.create("user_id")).build();
field.field().updateValue("user_12345"); // set only dummy value for debug
return field;
}
}
It would be possible to implement such an MDC manually, see https://www.baeldung.com/mdc-in-log4j-2-logback. But as this is error prone we want to avoid it, e.g. context cleaning must be done right.
How can the user id from JWT be added to MDC using sleuth/brave for server side logging?
I was using
spring boot version: 2.1.2.RELEASE
spring cloud version: Greenwich.RELEASE
and you can configure with following properties
spring.sleuth.propagation-keys=user_id
spring.sleuth.log.slf4j.whitelisted-mdc-keys=user_id
Since you are using
spring.sleuth.baggage.remote-fields=user_id
and it's working for you, this is how to create and update the value of Baggage Fields.
BaggageField baggageField = BaggageField.create(baggageKey);
baggageField.updateValue(baggageValue);
Do note that updating baggage value this way will show up in the logs from the next span. In case you want to update the value in the same span have a look at this answer https://stackoverflow.com/a/67373784/2224254
You can get the principal (username in your case) from Spring Security like this (assuming you are using the JWT as it should be):
SecurityContextHolder.getContext().getAuthentication().getPrincipal()
After this, you can add it to the MDC or set as a baggage field/tag/etc:
// assuming username is setup in sleuth.baggage.remote-keys
BaggageField USERNAME = BaggageField.create("username");
USERNAME.updateValue(span.context(), String.valueOf(SecurityContextHolder.getContext().getAuthentication().getPrincipal()));
Tags.BAGGAGE_FIELD.tag(USERNAME, span);
I'm using Spring Boot 2.2.4 with embedded Undertow.
I've enabled the access log using server.underdow.accesslog.enabled=true and everything works as expected.
I'm utilizing the actuator endpoints on a different port which sets up a child context. I do not want requests to the actuator to be logged. Currently they automatically go to management_access.log where access. is the prefix of my main access log.
Any ideas on how to disable that access log? I know Spring is creating a separate WebServer via Factory for the actuator context, but I haven't found a way to customize the factory.
I found my own answer (spent way too much time doing it).
It's a little bit of a hack, but it works:
New configuration class: foo.ManagementConfig
package foo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration;
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean;
#ManagementContextConfiguration
public class ManagementConfig {
#Bean
WebServerFactoryCustomizer<UndertowServletWebServerFactory> actuatorCustomizer(#Value("${management.server.port}") int managementPort) {
return factory -> {
if (managementPort == factory.getPort()) {
factory.setAccessLogEnabled(false);
}
};
}
}
Created resources/META-INF/spring.factories so that it gets picked up by the ManagementContext:
org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration=foo.ManagementConfig
The part that's a bit of a hack is the if statement. It would have been great if it applied only to the management context, but for some reason it's trying to apply to both. With the if statement, it just doesn't do anything for the primary context.
This would have unintended consequences if management.server.port was undefined or if it was the same as the primary context.
I'm beginning our migration from Apollo Client 2.x to 3.x beta, and I'm having trouble using both the apollo hooks and the now deprecated query/mutation components.
I'm using the packages:
#apollo/client: 3.0.0-beta.4
#apollo/react-components: 3.1.3
Using the apollo hooks works fine in this case, but using the query component, I get the following error:
Invariant Violation
Could not find "client" in the context or passed in as an option.
Wrap the root component in an , or pass an ApolloClient instance in via options.
I've created a codesandbox that shows this issue here:
https://codesandbox.io/s/react-example-9p9ym
I think the issue is with the source of the ApolloProvider I'm using, but not sure which package to get that from if I want to use the new beta, while still using the query components.
You should import ApolloProvider from the same package as the component or hook that's using it. That's because the context provided by ApolloProvider needs to be the same as the context being used by the component or hook. if you use different packages, the context object will be different.
The react-apollo package exports all three: ApolloProvider, Query and useQuery. If you use that package, you can use the ApolloProvider with both Query and useQuery. #apollo/client, however, only exports ApolloProvider and useQuery. That's because the graphql HOC and the render prop components have been deprecated. If you insist on using both Query and useQuery, you have to import Query from another package, like #apollo/react-components and add its ApolloProvider as well:
import {
ApolloProvider as ApolloProvider2,
Query,
} from '#apollo/react-components'
import {
ApolloProvider,
ApolloClient,
HttpLink,
InMemoryCache,
useQuery,
gql,
} from '#apollo/client'
<ApolloProvider2 client={client}>
<ApolloProvider client={client}>
<App/>
</ApolloProvider>
</ApolloProvider2>
Notice that you can import gql directly from apollo#client as well.
I have one bundle which has Import-Package org.osgi.service.cm. In this bundle there is only an interface ConfigurationInterface, that declares a couple of methods, one throws an org.osgi.service.cm.ConfigurationException. This bundle exports only its own package, lets say com.foo.bar.configuration.
Then I have other API bundles that have an interface for the service, ServiceInterface, that extends ConfigurationInterface, so they are importing the package com.foo.bar.configuration. Obviously there are also implementations bundle for these api that implement ServiceInterface, so they are importing org.osgi.service.cm because every implementations need to have the method that throws an org.osgi.service.cm.ConfigurationException.
Everything is working fine, the problems come out when I declare these services as optional, because when they are not available the framework tries to instantiate a proxy from the interface and I get a java.lang.ClassNotFoundException: org.osgi.service.cm.ConfigurationException. The framework suggests to add an import for 'org.osgi.service.cm' to the API bundle.
Is there a way to make this import available from the configuration bundle so that it is not necessary to add the import to every API?
i have some hard task, i need to change some part of my project using jboss portal 2.7.2 into liferay. Ofc less change better but all jboss portal must disappear. I need 2 replace classes below. So my question is how using liferay portal implements(or not(if already exist)) listener which will know when someone is trying 2 log in. Make login possible without reloading etc. Ofc it was nice if there was some pro eventlistener in liferay which can recognise other events not only logging but i will be glad for all help. 4 the rest of this class will be nice if someone know replacment 4 them in liferay.
import org.jboss.portal.api.event.PortalEvent;
import org.jboss.portal.api.event.PortalEventContext;
import org.jboss.portal.api.event.PortalEventListener;
import org.jboss.portal.api.session.PortalSession;
import org.jboss.portal.api.user.event.UserAuthenticationEvent;
import org.jboss.portal.identity.IdentityException;
import org.jboss.portal.identity.NoSuchUserException;
import org.jboss.portal.identity.User;
import org.jboss.portal.identity.UserModule;
import org.jboss.portal.identity.UserProfileModule;
Liferay has similar approache. Create a Hook and add properties like http://www.liferay.com/documentation/liferay-portal/6.1/development/-/ai/extending-and-overriding-%3Cem%3Eportal-properties%3C-e-1
With the properties you can specificy wich class schould be call by the portal events:
login.events.post=my.package.AfterLoginHandler
with the same approche you can listen to creating/changes/removes of entities:
value.object.listener.com.liferay.portal.model.User=my.package.UserListener
value.object.listener.com.liferay.portal.model.Layout=my.package.LayoutListener
...
Liferay does allow adding handlers to login events. More information can be found # http://www.learnercorner.in/topics?showTopic=16001