diff --git a/.env b/.env index d73f21df..2c2aaa9c 100644 --- a/.env +++ b/.env @@ -5,7 +5,10 @@ # The IP below should be swapped to your real IP or DNS name, like 192.168.88.248, etc. if testing from remote browsers or mobile devices ESHOP_EXTERNAL_DNS_NAME_OR_IP=localhost - +MINIO_PORT=9100 +MINIO_CONSOLE_PORT=9101 +MINIO_ROOT_USER=root +MINIO_ROOT_PASSWORD=admin123 # If the NAMESPACE env var is set, Dapr does not load any # component that does not specify the same namespace. NAMESPACE=eshop \ No newline at end of file diff --git a/.gitignore b/.gitignore index c47ba2d1..ac1f2553 100644 --- a/.gitignore +++ b/.gitignore @@ -374,4 +374,22 @@ MigrationBackup/ **/tempkey.rsa # macOS files -.DS_Store \ No newline at end of file +.DS_Store +/src/ApiGateways/Aggregators/Web.Shopping.HttpAggregator/.aspnet/DataProtection-Keys/key-26c59856-9ff6-469a-8a7c-d954f1b1669b.xml +/src/Services/Basket/Basket.API/.aspnet/DataProtection-Keys/key-c48680ef-d1e0-4988-9486-e0f1bfb2f268.xml +/src/Services/Identity/Identity.API/.aspnet/DataProtection-Keys/key-986ee17b-ff21-4a99-8917-f348faa16819.xml +/src/Services/Identity/Identity.API/keys/is-signing-key-EAA68BA13C0497676FE6C8154E4CB60D.json +/src/Services/Identity/Identity.API/keys/is-signing-key-C773B66C065AB0FF099B1FA96A8DA508.json +/src/Services/Identity/Identity.API/keys/is-signing-key-C13A9A73D69887B49EE224B7610EE44B.json +/src/Services/Identity/Identity.API/keys/is-signing-key-A146395E40C2B5665F0A76377B3E49BC.json +/src/Services/Identity/Identity.API/keys/is-signing-key-9C9A36C9FFCF89F1ED6BA432240C2E8C.json +/src/Services/Identity/Identity.API/keys/is-signing-key-6DDC6082EC29A1BB9CE5AD77483AF126.json +/src/Services/Identity/Identity.API/keys/is-signing-key-511F2270F9ECDA692F2CD351C2E3FD8A.json +/src/Services/Identity/Identity.API/keys/is-signing-key-3E93D8BFF96E2B87F1278BF88CC89461.json +/src/Services/Identity/Identity.API/keys/is-signing-key-245BE88025479B3CBC04D33D8F04B6DB.json +/src/Services/Identity/Identity.API/keys/is-signing-key-23AFA9F9104D9AA570D6C4771A65ABFA.json +/src/Services/Identity/Identity.API/keys/is-signing-key-22B27C69702109C30DDF13C5E8E156D8.json +/src/Services/Ordering/Ordering.API/.aspnet/DataProtection-Keys/key-b0c35976-b46c-41ab-8f3a-710334bfb345.xml +/src/Web/BlazorClient.Host/.aspnet/DataProtection-Keys/key-5495f7e4-a7fb-4723-a26b-613c3969fb3f.xml +/minio/data/.minio.sys/buckets/.minio.sys/buckets +/minio/data diff --git a/dapr/components/eshop-pubsub.yaml b/dapr/components/eshop-pubsub.yaml index f4235d45..715798ee 100644 --- a/dapr/components/eshop-pubsub.yaml +++ b/dapr/components/eshop-pubsub.yaml @@ -8,7 +8,7 @@ spec: version: v1 metadata: - name: host - value: "amqp://rabbitmq:5672" + value: "amqp://rabbitmq:4672" - name: durable value: "false" - name: deletedWhenUnused diff --git a/docker-compose.override.yml b/docker-compose.override.yml index 2e809122..3f3b9ee0 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -6,6 +6,18 @@ version: '3.4' # but values present in the environment vars at runtime will always override those defined inside the .env file services: + minio: + restart: always + command: ["minio", "server", "--console-address", ":9001", "/data"] + volumes: + - ./minio/data:/data + - ./minio/config:/root/.minio + ports: + - "9100:9000" + - "9101:9001" + environment: + - MINIO_ROOT_USER=${MINIO_ROOT_USER} + - MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD} maildev: ports: @@ -13,7 +25,7 @@ services: rabbitmq: ports: - - "5672:5672" + - "4672:5672" redis: image: redis:alpine @@ -31,7 +43,7 @@ services: - SA_PASSWORD=Pass@word - ACCEPT_EULA=Y ports: - - "5433:1433" + - "2433:1433" volumes: - eshop-sqldata:/var/opt/mssql @@ -76,6 +88,10 @@ services: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=http://0.0.0.0:80 - RetryMigrations=true + - Minio__Endpoint=minio:9000 + - Minio__SecretKey=${MINIO_ROOT_PASSWORD} + - Minio__BucketName=eshop-catalog + - Minio__AccessKey=${MINIO_ROOT_USER} - SeqServerUrl=http://seq # Temporarily while waiting for https://github.com/dapr/dotnet-sdk/issues/779 to get fixed. - ConnectionStrings__CatalogDB=Server=sqldata;Database=Microsoft.eShopOnDapr.Services.CatalogDb;User Id=sa;Password=Pass@word;TrustServerCertificate=true diff --git a/docker-compose.yml b/docker-compose.yml index f3fd556a..f818a51a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,6 +2,9 @@ version: '3.4' services: + minio: + image: minio/minio + maildev: image: maildev/maildev diff --git a/docs/media/zipkin-WEBSHOPPINGAPIGW.png b/docs/media/zipkin-WEBSHOPPINGAPIGW.png new file mode 100644 index 00000000..6ecd68c2 Binary files /dev/null and b/docs/media/zipkin-WEBSHOPPINGAPIGW.png differ diff --git a/src/ApiGateways/Envoy/envoy.yaml b/src/ApiGateways/Envoy/envoy.yaml index 511e988d..ea44ef00 100644 --- a/src/ApiGateways/Envoy/envoy.yaml +++ b/src/ApiGateways/Envoy/envoy.yaml @@ -31,12 +31,19 @@ static_resources: allow_headers: "authorization, content-type, x-requestid, x-requested-with, x-signalr-user-agent" allow_credentials: true routes: + - name: "x-pics" + match: + prefix: "x/c/pics/" + route: + auto_host_rewrite: true + prefix_rewrite: "x/pics/" + cluster: catalog - name: "pics" match: prefix: "/c/pics/" route: auto_host_rewrite: true - prefix_rewrite: "/pics/" + prefix_rewrite: "/api/v1/catalog/img/" #http://192.168.1.5:5202/c/pics/10.jpeg cluster: catalog - name: "c-short" match: diff --git a/src/Services/Catalog/Catalog.API/Catalog.API.csproj b/src/Services/Catalog/Catalog.API/Catalog.API.csproj index b00a09fd..98331833 100644 --- a/src/Services/Catalog/Catalog.API/Catalog.API.csproj +++ b/src/Services/Catalog/Catalog.API/Catalog.API.csproj @@ -20,6 +20,7 @@ + all diff --git a/src/Services/Catalog/Catalog.API/Controllers/MediaController.cs b/src/Services/Catalog/Catalog.API/Controllers/MediaController.cs new file mode 100644 index 00000000..3b27fc62 --- /dev/null +++ b/src/Services/Catalog/Catalog.API/Controllers/MediaController.cs @@ -0,0 +1,88 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using System.ComponentModel.DataAnnotations; +using System.IO; +using System.Threading.Tasks; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Options; +using Minio; +using Minio.DataModel; +using System.Collections.Generic; + +namespace Microsoft.eShopOnDapr.Services.Catalog.API.Controllers +{ + public class MediaController : Controller + { + IConfiguration Config { get; } + protected IOptionsMonitor OptionsMonitor { get; } + public MediaController(IConfiguration config) + { + Config = config; + } + + /// + /// 上传疵点图片 + /// + /// + /// + [HttpPost] + [Route("/api/v1/catalog/upload")] + public async Task Upload([Required] IFormFile file) + { + if (file != null && file.Length < 1) + { + } + string endpoint = Config["Minio:Endpoint"]; + string accessKey = Config["Minio:AccessKey"]; + string secretKey = Config["Minio:SecretKey"]; + string bucketName = Config["Minio:BucketName"]; + string domainHost = Config["Host"]; + MinioClient minio = new MinioClient() + .WithEndpoint(endpoint) + .WithCredentials(accessKey, secretKey) + .Build(); + using (Stream stream = file.OpenReadStream()) + { + Dictionary metaData = new Dictionary + { + { "Name", $"{file.Name}" } + }; + PutObjectArgs args = new PutObjectArgs() + .WithBucket(bucketName) + .WithObject(file.FileName) + .WithStreamData(stream) + .WithObjectSize(stream.Length) + .WithContentType("application/octet-stream") + .WithHeaders(metaData); + await minio.PutObjectAsync(args); + return Json(new { }); + } + } + /// + /// http://192.168.1.5:5101/api/v1/catalog/img/10.jpeg + /// + /// + /// + [HttpGet]// + [Route("/api/v1/catalog/img/{objectName}")] + public async Task GetFileAsync(string objectName = "hello.jpg") + { + string endpoint = Config["Minio:Endpoint"]; + string accessKey = Config["Minio:AccessKey"]; + string secretKey = Config["Minio:SecretKey"]; + var bucketName = Config["Minio:BucketName"]; + string fileName = Path.Combine(Directory.GetCurrentDirectory(), objectName); + + MinioClient minio = new MinioClient() + .WithEndpoint(endpoint) + .WithCredentials(accessKey, secretKey) + .Build(); + GetObjectArgs getObjectArgs = new GetObjectArgs() + .WithBucket(bucketName) + .WithObject(objectName) + .WithFile(fileName); + ObjectStat stat = await minio.GetObjectAsync(getObjectArgs); + return new PhysicalFileResult(fileName, stat.ContentType); + } + } +}