Channel::normalizeTransactionOptions()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
ccs 4
cts 4
cp 1
crap 2
1
<?php
2
3
/**
4
 * Copyright 2017 American Express Travel Related Services Company, Inc.
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 * http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
15
 * or implied. See the License for the specific language governing
16
 * permissions and limitations under the License.
17
 */
18
19
declare(strict_types=1);
20
21
namespace AmericanExpress\HyperledgerFabricClient\Channel;
22
23
use AmericanExpress\HyperledgerFabricClient\Chaincode\Chaincode;
24
use AmericanExpress\HyperledgerFabricClient\Exception\InvalidArgumentException;
25
use AmericanExpress\HyperledgerFabricClient\Exception\RuntimeException;
26
use AmericanExpress\HyperledgerFabricClient\Exception\ExceptionInterface;
27
use AmericanExpress\HyperledgerFabricClient\Peer\PeerCollectionInterface;
28
use AmericanExpress\HyperledgerFabricClient\Peer\PeerInterface;
29
use AmericanExpress\HyperledgerFabricClient\Peer\PeerOptionsInterface;
30
use AmericanExpress\HyperledgerFabricClient\Proposal\ResponseCollection;
31
use AmericanExpress\HyperledgerFabricClient\Proposal\ProposalProcessorInterface;
32
use AmericanExpress\HyperledgerFabricClient\ProtoFactory\ChannelHeaderFactory;
33
use AmericanExpress\HyperledgerFabricClient\ProtoFactory\ProposalFactory;
34
use AmericanExpress\HyperledgerFabricClient\Transaction\TransactionOptions;
35
use AmericanExpress\HyperledgerFabricClient\Identity\SerializedIdentityAwareHeaderGeneratorInterface;
36
use Assert\Assertion;
37
use Assert\AssertionFailedException;
38
use Hyperledger\Fabric\Protos\Peer\ChaincodeHeaderExtension;
39
use Hyperledger\Fabric\Protos\Peer\ChaincodeProposalPayload;
40
41
final class Channel implements ChannelInterface, PeerCollectionInterface
42
{
43
    /**
44
     * @var string
45
     */
46
    private $name;
47
48
    /**
49
     * @var ProposalProcessorInterface
50
     */
51
    private $client;
52
53
    /**
54
     * @var PeerInterface[] $peers
55
     */
56
    private $peers;
57
58
    /**
59
     * @var SerializedIdentityAwareHeaderGeneratorInterface
60
     */
61
    private $headerGenerator;
62
63
    /**
64
     * @param string $name
65
     * @param ProposalProcessorInterface $client
66
     * @param SerializedIdentityAwareHeaderGeneratorInterface $userAwareHeaderGenerator
67
     * @param PeerOptionsInterface[] $peers
68
     * @throws InvalidArgumentException
69
     */
70 13
    public function __construct(
71
        string $name,
72
        ProposalProcessorInterface $client,
73
        SerializedIdentityAwareHeaderGeneratorInterface $userAwareHeaderGenerator,
74
        array $peers = []
75
    ) {
76
        try {
77 13
            Assertion::allIsInstanceOf($peers, PeerInterface::class);
78 1
        } catch (AssertionFailedException $e) {
79 1
            throw new InvalidArgumentException(
80 1
                sprintf('Failed to create Channel `%s` due to invalid Peer collection.', $name),
81 1
                0,
82 1
                $e
83
            );
84
        }
85
86 13
        $this->name = $name;
87 13
        $this->client = $client;
88 13
        $this->headerGenerator = $userAwareHeaderGenerator;
89 13
        $this->peers = $peers;
0 ignored issues
show
Documentation Bug introduced by
$peers is of type array<mixed,AmericanExpr...OptionsInterface|mixed>, but the property $peers was declared to be of type AmericanExpress\Hyperled...nt\Peer\PeerInterface[]. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
90 13
    }
91
92
    /**
93
     *
94
     * Returns a named Chaincode for a channel
95
     *
96
     * @param string | array $nameOrVersionedName
97
     * @return Chaincode
98
     * @throws InvalidArgumentException
99
     */
100 2
    public function getChaincode($nameOrVersionedName): Chaincode
101
    {
102
        try {
103 2
            return new Chaincode($nameOrVersionedName, $this);
104 1
        } catch (ExceptionInterface $e) {
105 1
            throw new InvalidArgumentException('Can not create Chaincode as requested', 0, $e);
106
        }
107
    }
108
109
    /**
110
     * @param PeerInterface[] ...$peers
111
     * @return void
112
     */
113 3
    public function addPeers(PeerInterface ...$peers): void
114
    {
115 3
        $this->peers = array_merge($this->peers, $peers);
116 3
    }
117
118
    /**
119
     * @param PeerInterface[] $peers
120
     * @return void
121
     */
122 1
    public function setPeers(array $peers): void
123
    {
124 1
        $this->peers = [];
125 1
        $this->addPeers(...$peers);
126 1
    }
127
128
    /**
129
     * @return PeerInterface[]
130
     */
131 7
    public function getPeers(): array
132
    {
133 7
        return $this->peers;
134
    }
135
136
    /**
137
     * @param TransactionOptions|null $options
138
     * @return PeerInterface[]
139
     */
140 5
    private function resolvePeers(TransactionOptions $options): array
141
    {
142 5
        if ($options->hasPeers()) {
143 3
            return $options->getPeers();
144
        }
145
146 2
        return $this->getPeers();
147
    }
148
149
    /**
150
     * @param TransactionOptions|null $options
151
     * @return TransactionOptions
152
     */
153 5
    private function normalizeTransactionOptions(TransactionOptions $options = null): TransactionOptions
154
    {
155 5
        if ($options === null) {
156 2
            $options = new TransactionOptions();
157
        }
158
159 5
        return $options->withPeers(...$this->resolvePeers($options));
160
    }
161
162
    /**
163
     *
164
     * Envelopes a Chaincode function invocation from a Chaincode object
165
     *
166
     * @param ChaincodeProposalPayload $payload
167
     * @param ChaincodeHeaderExtension $extension
168
     * @param TransactionOptions|null $options
169
     * @return ResponseCollection
170
     * @throws RuntimeException
171
     */
172 5
    public function processChaincodeProposal(
173
        ChaincodeProposalPayload $payload,
174
        ChaincodeHeaderExtension $extension,
175
        TransactionOptions $options = null
176
    ): ResponseCollection {
177 5
        $channelHeader = ChannelHeaderFactory::create($this->name);
178 5
        $channelHeader->setExtension($extension->serializeToString());
179
180 5
        $options = $this->normalizeTransactionOptions($options);
181 5
        if (!$options->hasPeers()) {
182 1
            throw new RuntimeException('Could not determine peers for this transaction');
183
        }
184
185 4
        $header = $this->headerGenerator->generateHeader($channelHeader);
186 4
        $proposal = ProposalFactory::create($header, $payload->serializeToString());
187
188
        try {
189 4
            return $this->client->processProposal($proposal, $options);
190 1
        } catch (ExceptionInterface $e) {
191 1
            throw new RuntimeException(
192 1
                'Unable to process Chaincode proposal',
193 1
                0,
194 1
                $e
195
            );
196
        }
197
    }
198
}
199